diff options
Diffstat (limited to 'mips/rtl')
50 files changed, 1296 insertions, 277 deletions
diff --git a/mips/rtl/arm/arm.inc b/mips/rtl/arm/arm.inc index 3387ff8e16..65bcb64d1f 100644 --- a/mips/rtl/arm/arm.inc +++ b/mips/rtl/arm/arm.inc @@ -52,7 +52,7 @@ begin // mask "exception happened" and overflow flags and r0,r0,#0xffffff20 // mask exception flags - and r0,r0,#0xffff40ff + and r0,r0,#0xffff40ff {$ifndef darwin} // Floating point exceptions cause kernel panics on iPhoneOS 2.2.1... @@ -110,7 +110,7 @@ end; {$ENDIF not INTERNAL_BACKTRACE} {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR} -function get_caller_addr(framebp:pointer):pointer;assembler;nostackframe; +function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;assembler;nostackframe; asm cmp r0,#0 {$ifndef darwin} @@ -122,7 +122,7 @@ end; {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME} -function get_caller_frame(framebp:pointer):pointer;assembler;nostackframe; +function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;assembler;nostackframe; asm cmp r0,#0 {$ifndef darwin} @@ -145,62 +145,69 @@ end; Procedure FillChar(var x;count:longint;value:byte);assembler;nostackframe; asm // less than 0? - cmp r1,#0 -{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)} - movlt pc,lr + cmp r1,#0 +{$if defined(cpuarmv3) or defined(cpuarmv4)} + movle pc,lr {$else} - bxlt lr + bxle lr {$endif} mov r3,r0 - cmp r1,#8 // at least 8 bytes to do? - blt .LFillchar2 - orr r2,r2,r2,lsl #8 - orr r2,r2,r2,lsl #16 -.LFillchar0: - tst r3,#3 // aligned yet? - strneb r2,[r3],#1 - subne r1,r1,#1 - bne .LFillchar0 + + orr r2,r2,r2,lsl #8 + orr r2,r2,r2,lsl #16 + + tst r3, #3 // Aligned? + bne .LFillchar_do_align + +.LFillchar_is_aligned: + subs r1,r1,#8 + bmi .LFillchar_less_than_8bytes + mov ip,r2 -.LFillchar1: - cmp r1,#8 // 8 bytes still to do? - blt .LFillchar2 - stmia r3!,{r2,ip} - sub r1,r1,#8 - cmp r1,#8 // 8 bytes still to do? - blt .LFillchar2 +.LFillchar_at_least_8bytes: + // Do 16 bytes per loop + // More unrolling is uncessary, as we'll just stall on the write buffers stmia r3!,{r2,ip} - sub r1,r1,#8 - cmp r1,#8 // 8 bytes still to do? - blt .LFillchar2 - stmia r3!,{r2,ip} - sub r1,r1,#8 - cmp r1,#8 // 8 bytes still to do? - stmgeia r3!,{r2,ip} - subge r1,r1,#8 - bge .LFillchar1 -.LFillchar2: - movs r1,r1 // anything left? -{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)} + subs r1,r1,#8 + stmplia r3!,{r2,ip} + subpls r1,r1,#8 + bpl .LFillchar_at_least_8bytes + +.LFillchar_less_than_8bytes: + // Do the rest + adds r1, r1, #8 + +{$if defined(cpuarmv3) or defined(cpuarmv4)} moveq pc,lr {$else} bxeq lr {$endif} - rsb r1,r1,#7 - add pc,pc,r1,lsl #2 - mov r0,r0 - strb r2,[r3],#1 - strb r2,[r3],#1 - strb r2,[r3],#1 - strb r2,[r3],#1 - strb r2,[r3],#1 - strb r2,[r3],#1 - strb r2,[r3],#1 -{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)} + + tst r1, #4 + strne r2,[r3],#4 + tst r1, #2 + strneh r2,[r3],#2 + tst r1, #1 + strneb r2,[r3],#1 +{$if defined(cpuarmv3) or defined(cpuarmv4)} mov pc,lr {$else} bx lr {$endif} + +// Special case for unaligned start +// We make a maximum of 3 loops here +.LFillchar_do_align: + strb r2,[r3],#1 + subs r1, r1, #1 +{$if defined(cpuarmv3) or defined(cpuarmv4)} + moveq pc,lr +{$else} + bxeq lr +{$endif} + tst r3,#3 + bne .LFillchar_do_align + b .LFillchar_is_aligned end; {$endif FPC_SYSTEM_HAS_FILLCHAR} @@ -211,7 +218,7 @@ asm pld [r0] // count <=0 ? cmp r2,#0 -{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)} +{$if defined(cpuarmv3) or defined(cpuarmv4)} movle pc,lr {$else} bxle lr @@ -228,7 +235,7 @@ asm ldrb r3,[r0,r2] strb r3,[r1,r2] bne .Loverlapped -{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)} +{$if defined(cpuarmv3) or defined(cpuarmv4)} mov pc,lr {$else} bx lr @@ -273,7 +280,7 @@ asm str r3,[r1],#4 bcs .Ldwordloop cmp r2,#0 -{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)} +{$if defined(cpuarmv3) or defined(cpuarmv4)} moveq pc,lr {$else} bxeq lr @@ -283,7 +290,7 @@ asm ldrb r3,[r0],#1 strb r3,[r1],#1 bne .Lbyteloop -{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)} +{$if defined(cpuarmv3) or defined(cpuarmv4)} mov pc,lr {$else} bx lr @@ -294,7 +301,7 @@ procedure Move_blended(const source;var dest;count:longint);assembler;nostackfra asm // count <=0 ? cmp r2,#0 -{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)} +{$if defined(cpuarmv3) or defined(cpuarmv4)} movle pc,lr {$else} bxle lr @@ -311,7 +318,7 @@ asm ldrb r3,[r0,r2] strb r3,[r1,r2] bne .Loverlapped -{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)} +{$if defined(cpuarmv3) or defined(cpuarmv4)} mov pc,lr {$else} bx lr @@ -353,7 +360,7 @@ asm str r3,[r1],#4 bcs .Ldwordloop cmp r2,#0 -{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)} +{$if defined(cpuarmv3) or defined(cpuarmv4)} moveq pc,lr {$else} bxeq lr @@ -363,7 +370,7 @@ asm ldrb r3,[r0],#1 strb r3,[r1],#1 bne .Lbyteloop -{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)} +{$if defined(cpuarmv3) or defined(cpuarmv4)} mov pc,lr {$else} bx lr @@ -542,7 +549,7 @@ asm terminating 0, due to the known carry flag sbc can do this.*) sbc r0,r1,r0 .Ldone: -{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)} +{$if defined(cpuarmv3) or defined(cpuarmv4)} mov pc,lr {$else} bx lr diff --git a/mips/rtl/arm/divide.inc b/mips/rtl/arm/divide.inc index 8df2a6524f..42dfe7dd58 100644 --- a/mips/rtl/arm/divide.inc +++ b/mips/rtl/arm/divide.inc @@ -96,7 +96,7 @@ asm .Ldiv_next: bcs .Ldiv_loop mov r0, r3 -{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)} +{$if defined(cpuarmv3) or defined(cpuarmv4)} mov pc, lr {$else} bx lr @@ -105,7 +105,7 @@ asm mov r0, #200 mov r1, r11 bl handleerrorframe -{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)} +{$if defined(cpuarmv3) or defined(cpuarmv4)} mov pc, lr {$else} bx lr diff --git a/mips/rtl/arm/strings.inc b/mips/rtl/arm/strings.inc index 388f2e0626..f3512975b6 100644 --- a/mips/rtl/arm/strings.inc +++ b/mips/rtl/arm/strings.inc @@ -15,3 +15,50 @@ **********************************************************************} +{$ifndef FPC_UNIT_HAS_STRUPPER} +{$define FPC_UNIT_HAS_STRUPPER} +function strupper(p : pchar) : pchar;assembler;nostackframe; +asm + mov ip, r0 // Don't change r0, because thats our return value + + ldrb r1, [ip] // First loop does not postindex +.LByteLoop: + cmp r1, #0 +{$if defined(cpuarmv3) or defined(cpuarmv4)} + moveq pc, lr +{$else} + bxeq lr +{$endif} + + sub r2, r1, #97 // Normalize to zero + cmp r2, #25 // temp >= 0 and temp <=25 + subls r1, r1, #32 // is lowercase, make uppercase + strlsb r1, [ip] // Store only on change + ldrb r1, [ip, #1]! // Loading here utilizes a load delay slot + b .LByteLoop +end; +{$endif FPC_UNIT_HAS_STRUPPER} + +{$ifndef FPC_UNIT_HAS_STRLOWER} +{$define FPC_UNIT_HAS_STRLOWER} +function strlower(p : pchar) : pchar;assembler;nostackframe; +asm + mov ip, r0 // Don't change r0, because thats our return value + + ldrb r1, [ip] // First loop does not postindex +.LByteLoop: + cmp r1, #0 +{$if defined(cpuarmv3) or defined(cpuarmv4)} + moveq pc, lr +{$else} + bxeq lr +{$endif} + + sub r2, r1, #65 // Normalize to zero + cmp r2, #25 // temp >= 0 and temp <=25 + addls r1, r1, #32 // Is uppercase, make lowercase + strlsb r1, [ip] // Store only on change + ldrb r1, [ip, #1]! // Loading here utilizes a load delay slot + b .LByteLoop +end; +{$endif FPC_UNIT_HAS_STRLOWER} diff --git a/mips/rtl/avr/avr.inc b/mips/rtl/avr/avr.inc index e9d93e85b1..2ad61f5a07 100644 --- a/mips/rtl/avr/avr.inc +++ b/mips/rtl/avr/avr.inc @@ -38,13 +38,13 @@ function get_frame:pointer;assembler;nostackframe; {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR} -function get_caller_addr(framebp:pointer):pointer;assembler; +function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;assembler; asm end; {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME} -function get_caller_frame(framebp:pointer):pointer;assembler; +function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;assembler; asm end; diff --git a/mips/rtl/i386/i386.inc b/mips/rtl/i386/i386.inc index 368c7a02f4..9fb8a7d724 100644 --- a/mips/rtl/i386/i386.inc +++ b/mips/rtl/i386/i386.inc @@ -1061,8 +1061,14 @@ end; {$ENDIF not INTERNAL_BACKTRACE} +{$define FPC_SYSTEM_HAS_GET_PC_ADDR} +Function Get_pc_addr : Pointer;assembler;nostackframe; +asm + movl (%esp),%eax +end; + {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR} -function get_caller_addr(framebp:pointer):pointer;nostackframe;assembler; +function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;nostackframe;assembler; asm orl %eax,%eax jz .Lg_a_null @@ -1072,7 +1078,7 @@ end; {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME} -function get_caller_frame(framebp:pointer):pointer;nostackframe;assembler; +function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;nostackframe;assembler; asm orl %eax,%eax jz .Lgnf_null diff --git a/mips/rtl/inc/compproc.inc b/mips/rtl/inc/compproc.inc index 0a7d9ccc7f..8024c715d3 100644 --- a/mips/rtl/inc/compproc.inc +++ b/mips/rtl/inc/compproc.inc @@ -40,6 +40,7 @@ procedure fpc_zeromem(p:pointer;len:ptruint);compilerproc; procedure fpc_fillmem(out data;len:ptruint;b : byte);compilerproc; procedure fpc_Shortstr_SetLength(var s:shortstring;len:SizeInt); compilerproc; +procedure fpc_shortstr_assign(len:longint;sstr,dstr:pointer); compilerproc; procedure fpc_shortstr_to_shortstr(out res:shortstring; const sstr: shortstring); compilerproc; procedure fpc_shortstr_concat(var dests:shortstring;const s1,s2:shortstring);compilerproc; @@ -421,7 +422,7 @@ procedure fpc_variant_init(var v: tvardata);compilerproc; procedure fpc_variant_clear(var v: tvardata);compilerproc; {$ifdef FPC_VARIANTCOPY_FIXED} procedure fpc_variant_copy(var d: tvardata; const s : tvardata);compilerproc; -procedure fpc_variant_copy_overwrite(const source: tvardata; var dest : tvardata);compilerproc; +procedure fpc_variant_copy_overwrite(constref source: tvardata; var dest : tvardata);compilerproc; {$else FPC_VARIANTCOPY_FIXED} procedure fpc_variant_copy(d,s : pointer);compilerproc; procedure fpc_variant_copy_overwrite(source, dest : pointer);compilerproc; diff --git a/mips/rtl/inc/except.inc b/mips/rtl/inc/except.inc index e1b4839d8a..e9343dfcb3 100644 --- a/mips/rtl/inc/except.inc +++ b/mips/rtl/inc/except.inc @@ -102,6 +102,7 @@ var frames : PPointer; prev_frame, curr_frame, + curr_addr, caller_frame, caller_addr : Pointer; begin @@ -119,15 +120,16 @@ begin { Backtrace } curr_frame:=AFrame; - prev_frame:=get_frame; + curr_addr:=AnAddr; + prev_frame:=get_caller_frame(curr_addr, curr_frame); frames:=nil; framebufsize:=0; framecount:=0; while (framecount<RaiseMaxFrameCount) and (curr_frame > prev_frame) and (curr_frame<(StackBottom + StackLength)) do Begin - caller_addr := get_caller_addr(curr_frame); - caller_frame := get_caller_frame(curr_frame); + caller_addr := get_caller_addr(curr_frame, curr_addr); + caller_frame := get_caller_frame(curr_frame, curr_addr); if (caller_addr=nil) or (caller_frame=nil) then break; @@ -139,6 +141,7 @@ begin frames[framecount]:=caller_addr; inc(framecount); prev_frame:=curr_frame; + curr_addr:=caller_addr; curr_frame:=caller_frame; End; NewObj^.framecount:=framecount; diff --git a/mips/rtl/inc/generic.inc b/mips/rtl/inc/generic.inc index 87e0a46699..7c351a666c 100644 --- a/mips/rtl/inc/generic.inc +++ b/mips/rtl/inc/generic.inc @@ -892,7 +892,7 @@ begin res[0]:=chr(slen); end; -procedure fpc_shortstr_assign(len:longint;sstr,dstr:pointer);[public,alias:'FPC_SHORTSTR_ASSIGN']; +procedure fpc_shortstr_assign(len:longint;sstr,dstr:pointer);[public,alias:'FPC_SHORTSTR_ASSIGN']; compilerproc; var slen : byte; begin diff --git a/mips/rtl/inc/heaptrc.pp b/mips/rtl/inc/heaptrc.pp index 9963a40e01..1099cc5927 100644 --- a/mips/rtl/inc/heaptrc.pp +++ b/mips/rtl/inc/heaptrc.pp @@ -331,14 +331,21 @@ end; procedure dump_already_free(p : pheap_mem_info;var ptext : text); +var + bp, pcaddr : pointer; begin Writeln(ptext,'Marked memory at $',HexStr(pointer(p)+sizeof(theap_mem_info)),' released'); call_free_stack(p,ptext); Writeln(ptext,'freed again at'); - dump_stack(ptext,get_caller_frame(get_frame)); + bp:=get_frame; + pcaddr:=get_pc_addr; + get_caller_stackinfo(bp,pcaddr); + dump_stack(ptext,bp,pcaddr); end; procedure dump_error(p : pheap_mem_info;var ptext : text); +var + bp, pcaddr : pointer; begin Writeln(ptext,'Marked memory at $',HexStr(pointer(p)+sizeof(theap_mem_info)),' invalid'); Writeln(ptext,'Wrong signature $',hexstr(p^.sig,8),' instead of ',hexstr(calculate_sig(p),8)); @@ -347,7 +354,10 @@ begin write(ptext, 'Block content: '); printhex(pointer(p) + sizeof(theap_mem_info), p^.size, ptext); end; - dump_stack(ptext,get_caller_frame(get_frame)); + bp:=get_frame; + pcaddr:=get_pc_addr; + get_caller_stackinfo(bp,pcaddr); + dump_stack(ptext,bp,pcaddr); end; {$ifdef EXTRA} @@ -367,10 +377,15 @@ end; {$endif EXTRA} procedure dump_wrong_size(p : pheap_mem_info;size : ptruint;var ptext : text); +var + bp, pcaddr : pointer; begin Writeln(ptext,'Marked memory at $',HexStr(pointer(p)+sizeof(theap_mem_info)),' invalid'); Writeln(ptext,'Wrong size : ',p^.size,' allocated ',size,' freed'); - dump_stack(ptext,get_caller_frame(get_frame)); + bp:=get_frame; + pcaddr:=get_pc_addr; + get_caller_stackinfo(bp,pcaddr); + dump_stack(ptext,bp,pcaddr); { the check is done to be sure that the procvar is not overwritten } if assigned(p^.extra_info) and (p^.extra_info^.check=$12345678) and @@ -445,7 +460,7 @@ Function TraceGetMem(size:ptruint):pointer; var allocsize,i : ptruint; oldbp, - bp : pointer; + bp,pcaddr : pointer; pl : pdword; p : pointer; pp : pheap_mem_info; @@ -509,15 +524,16 @@ begin { clear the memory } fillchar(p^,size,#255); { retrieve backtrace info } - bp:=get_caller_frame(get_frame); - + bp:=get_frame; + pcaddr:=get_pc_addr; + get_caller_stackinfo(bp,pcaddr); { valid bp? } if (bp>=StackBottom) and (bp<(StackBottom + StackLength)) then for i:=1 to tracesize do begin - pp^.calls[i]:=get_caller_addr(bp); oldbp:=bp; - bp:=get_caller_frame(bp); + get_caller_stackinfo(bp,pcaddr); + pp^.calls[i]:=pcaddr; if (bp<oldbp) or (bp>(StackBottom + StackLength)) then break; end; @@ -553,7 +569,7 @@ function CheckFreeMemSize(loc_info: pheap_info; pp: pheap_mem_info; size, ppsize: ptruint): boolean; inline; var i: ptruint; - bp : pointer; + bp,pcaddr : pointer; ptext : ^text; {$ifdef EXTRA} pp2 : pheap_mem_info; @@ -612,12 +628,15 @@ begin end else begin - bp:=get_caller_frame(get_frame); + bp:=get_frame; + pcaddr:=get_pc_addr; + get_caller_stackinfo(bp,pcaddr); + if (bp>=StackBottom) and (bp<(StackBottom + StackLength)) then for i:=(tracesize div 2)+1 to tracesize do begin - pp^.calls[i]:=get_caller_addr(bp); - bp:=get_caller_frame(bp); + get_caller_stackinfo(bp,pcaddr); + pp^.calls[i]:=pcaddr; if not((bp>=StackBottom) and (bp<(StackBottom + StackLength))) then break; end; @@ -775,7 +794,8 @@ var movesize, i : ptruint; oldbp, - bp : pointer; + bp, + pcaddr : pointer; pl : pdword; pp : pheap_mem_info; oldsize, @@ -890,13 +910,15 @@ begin inc(loc_info^.getmem_size,size); inc(loc_info^.getmem8_size,(size+7) and not 7); { generate new backtrace } - bp:=get_caller_frame(get_frame); + bp:=get_frame; + pcaddr:=get_pc_addr; + get_caller_stackinfo(bp,pcaddr); if (bp>=StackBottom) and (bp<(StackBottom + StackLength)) then for i:=1 to tracesize do begin - pp^.calls[i]:=get_caller_addr(bp); oldbp:=bp; - bp:=get_caller_frame(bp); + get_caller_stackinfo(bp,pcaddr); + pp^.calls[i]:=pcaddr; if (bp<oldbp) or (bp>(StackBottom + StackLength)) then break; end; @@ -979,6 +1001,7 @@ var {$ifdef morphos} stack_top: longword; {$endif morphos} + bp,pcaddr : pointer; ptext : ^text; label _exit; @@ -1136,7 +1159,10 @@ begin end; end; writeln(ptext^,'pointer $',hexstr(p),' does not point to valid memory block'); - dump_stack(ptext^,get_caller_frame(get_frame)); + bp:=get_frame; + pcaddr:=get_pc_addr; + get_caller_stackinfo(bp,pcaddr); + dump_stack(ptext^,bp,pcaddr); runerror(204); _exit: end; diff --git a/mips/rtl/inc/system.inc b/mips/rtl/inc/system.inc index 25d04d563b..47d5d97e95 100644 --- a/mips/rtl/inc/system.inc +++ b/mips/rtl/inc/system.inc @@ -78,6 +78,7 @@ Const Procedure HandleError (Errno : Longint); forward; Procedure HandleErrorFrame (Errno : longint;frame : Pointer); forward; +Procedure HandleErrorAddrFrame (Errno : longint;addr,frame : Pointer); forward; {$ifdef FPC_HAS_FEATURE_TEXTIO} type @@ -668,33 +669,60 @@ End; Miscellaneous *****************************************************************************} +{$ifndef FPC_SYSTEM_HAS_GET_PC_ADDR} + { This provides a dummy implementation + of get_pc_addr function, for CPU's that don't need + the instruction address to walk the stack. } +function get_pc_addr : pointer; +begin + get_pc_addr:=nil; +end; +{$endif ndef FPC_SYSTEM_HAS_GET_PC_ADDR} + +{$ifndef FPC_SYSTEM_HAS_GET_CALLER_STACKINFO} + { This provides a simpel implementation + of get_caller_stackinfo procedure, + using get_caller_addr and get_caller_frame + functions. } +procedure get_caller_stackinfo(var framebp,addr : pointer); +var + nextbp,nextaddr : pointer; +begin + nextbp:=get_caller_frame(framebp,addr); + nextaddr:=get_caller_addr(framebp,addr); + framebp:=nextbp; + addr:=nextaddr; +end; +{$endif ndef FPC_SYSTEM_HAS_GET_CALLER_STACKINFO} + + procedure fpc_rangeerror;[public,alias:'FPC_RANGEERROR']; compilerproc; begin - HandleErrorFrame(201,get_frame); + HandleErrorAddrFrame(201,get_pc_addr,get_frame); end; procedure fpc_divbyzero;[public,alias:'FPC_DIVBYZERO']; compilerproc; begin - HandleErrorFrame(200,get_frame); + HandleErrorAddrFrame(200,get_pc_addr,get_frame); end; procedure fpc_overflow;[public,alias:'FPC_OVERFLOW']; compilerproc; begin - HandleErrorFrame(215,get_frame); + HandleErrorAddrFrame(215,get_pc_addr,get_frame); end; procedure fpc_threaderror; [public,alias:'FPC_THREADERROR']; begin - HandleErrorFrame(6,get_frame); + HandleErrorAddrFrame(6,get_pc_addr,get_frame); end; procedure fpc_invalidpointer; [public,alias:'FPC_INVALIDPOINTER']; begin - HandleErrorFrame(216,get_frame); + HandleErrorAddrFrame(216,get_pc_addr,get_frame); end; @@ -708,7 +736,7 @@ begin begin l:=HInOutRes^; HInOutRes^:=0; - HandleErrorFrame(l,get_frame); + HandleErrorAddrFrame(l,get_pc_addr,get_frame); end; end; @@ -737,7 +765,7 @@ begin begin if assigned(SafeCallErrorProc) then SafeCallErrorProc(res,get_frame); - HandleErrorFrame(229,get_frame); + HandleErrorAddrFrame(229,get_pc_addr,get_frame); end; result:=res; end; @@ -1024,15 +1052,20 @@ Procedure HandleError (Errno : longint);[public,alias : 'FPC_HANDLEERROR']; Internal function should ALWAYS call HandleError instead of RunError. } begin - HandleErrorFrame(Errno,get_frame); + HandleErrorAddrFrame(Errno,get_pc_addr,get_frame); end; procedure RunError(w : word);[alias: 'FPC_RUNERROR']; +var + bp,pcaddr : pointer; begin errorcode:=w; - erroraddr:=get_caller_addr(get_frame); - errorbase:=get_caller_frame(get_frame); + pcaddr:=get_pc_addr; + bp:=get_frame; + get_caller_stackinfo(bp,pcaddr); + erroraddr:=pcaddr; + errorbase:=bp; Halt(errorcode); end; @@ -1055,10 +1088,11 @@ begin end; -Procedure dump_stack(var f : text;bp : Pointer); +Procedure dump_stack(var f : text;bp,addr : Pointer); var i : Longint; prevbp : Pointer; + prevaddr : pointer; is_dev : boolean; caller_frame, caller_addr : Pointer; @@ -1067,12 +1101,13 @@ Begin try {$endif FPC_HAS_FEATURE_EXCEPTIONS} prevbp:=bp-1; + prevaddr:=nil; i:=0; is_dev:=do_isdevice(textrec(f).Handle); while bp > prevbp Do Begin - caller_addr := get_caller_addr(bp); - caller_frame := get_caller_frame(bp); + caller_addr := get_caller_addr(bp,addr); + caller_frame := get_caller_frame(bp,addr); if (caller_addr=nil) then break; Writeln(f,BackTraceStrFunc(caller_addr)); @@ -1082,7 +1117,9 @@ Begin If ((i>max_frame_dump) and is_dev) or (i>256) Then break; prevbp:=bp; + prevaddr:=addr; bp:=caller_frame; + addr:=caller_addr; End; {$ifdef FPC_HAS_FEATURE_EXCEPTIONS} except @@ -1268,16 +1305,17 @@ procedure fpc_AbstractErrorIntern;compilerproc;[public,alias : 'FPC_ABSTRACTERRO begin If pointer(AbstractErrorProc)<>nil then AbstractErrorProc(); - HandleErrorFrame(211,get_frame); + HandleErrorAddrFrame(211,get_pc_addr,get_frame); end; -Procedure fpc_assert(Const Msg,FName:Shortstring;LineNo:Longint;ErrorAddr:Pointer); [Public,Alias : 'FPC_ASSERT']; compilerproc; +Procedure fpc_assert(Const Msg,FName:Shortstring;LineNo:Longint; + ErrorAddr:Pointer); [Public,Alias : 'FPC_ASSERT']; compilerproc; begin if pointer(AssertErrorProc)<>nil then AssertErrorProc(Msg,FName,LineNo,ErrorAddr) else - HandleErrorFrame(227,get_frame); + HandleErrorAddrFrame(227,get_pc_addr,get_frame); end; diff --git a/mips/rtl/inc/systemh.inc b/mips/rtl/inc/systemh.inc index 511a4487a1..a4715dd2a9 100644 --- a/mips/rtl/inc/systemh.inc +++ b/mips/rtl/inc/systemh.inc @@ -644,7 +644,7 @@ Function Random: extended; Procedure Randomize; {$endif FPC_HAS_FEATURE_RANDOM} -{$ifdef FPC_HAS_INTERNAL_ABS_LONG and (defined(cpui386) or defined(cpux86_64) or defined(cpupowerpc))} +{$ifdef FPC_HAS_INTERNAL_ABS_LONG} {$define FPC_SYSTEM_HAS_ABS_LONGINT} Function abs(l:longint):longint;[internproc:fpc_in_abs_long]; {$else FPC_HAS_INTERNAL_ABS_LONG} @@ -1059,15 +1059,18 @@ Procedure getdir(drivenr:byte;var dir:ansistring); //function get_frame:pointer;[INTERNPROC:fpc_in_get_frame]; (* // still defined externally -function get_caller_addr(framebp:pointer):pointer;[INTERNPROC:fpc_in_get_caller_addr]; -function get_caller_frame(framebp:pointer):pointer;[INTERNPROC:fpc_in_get_caller_frame]; +function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;[INTERNPROC:fpc_in_get_caller_addr]; +function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;[INTERNPROC:fpc_in_get_caller_frame]; *) {$ELSE} function get_frame:pointer;{$ifdef SYSTEMINLINE}inline;{$endif} {$ENDIF} -function get_caller_addr(framebp:pointer):pointer; -function get_caller_frame(framebp:pointer):pointer; +Function Get_pc_addr : Pointer; + +function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer; +function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer; +procedure get_caller_stackinfo(var framebp,addr : pointer); Function IOResult:Word; Function Sptr:Pointer;[internconst:fpc_in_const_ptr]; @@ -1149,7 +1152,7 @@ Function Paramcount:Longint; Function ParamStr(l:Longint):string; {$endif FPC_HAS_FEATURE_COMMANDARGS} -Procedure Dump_Stack(var f : text;bp:pointer); +Procedure Dump_Stack(var f : text;bp:pointer;addr : pointer = nil); {$ifdef FPC_HAS_FEATURE_EXCEPTIONS} procedure DumpExceptionBackTrace(var f:text); {$endif FPC_HAS_FEATURE_EXCEPTIONS} diff --git a/mips/rtl/inc/variant.inc b/mips/rtl/inc/variant.inc index 19cf9b4569..b41465346d 100644 --- a/mips/rtl/inc/variant.inc +++ b/mips/rtl/inc/variant.inc @@ -52,7 +52,7 @@ procedure fpc_variant_copy(var d: tvardata; const s : tvardata);[Public,Alias:'F VarCopyProc(d,s); end; -procedure fpc_variant_copy_overwrite(const source: tvardata; var dest : tvardata);[Public,Alias:'FPC_VARIANT_COPY_OVERWRITE']; compilerproc; +procedure fpc_variant_copy_overwrite(constref source: tvardata; var dest : tvardata);[Public,Alias:'FPC_VARIANT_COPY_OVERWRITE']; compilerproc; begin dest.VType := varEmpty; if assigned(VarCopyProc) then diff --git a/mips/rtl/java/jastringh.inc b/mips/rtl/java/jastringh.inc index 2a4fcb0ea4..1570e13749 100644 --- a/mips/rtl/java/jastringh.inc +++ b/mips/rtl/java/jastringh.inc @@ -26,6 +26,7 @@ type constructor Create(len: longint; cp: TSystemCodePage);overload; constructor Create(const arr: array of ansichar; length: longint; cp: TSystemCodePage);overload; constructor Create(const arr: array of unicodechar; cp: TSystemCodePage);overload; + constructor Create(const u: unicodestring);overload; constructor Create(const u: unicodestring; cp: TSystemCodePage);overload; constructor Create(const a: RawByteString; cp: TSystemCodePage);overload; constructor Create(const s: shortstring; cp: TSystemCodePage);overload; diff --git a/mips/rtl/java/jastrings.inc b/mips/rtl/java/jastrings.inc index 6eccb4827f..276f7829ca 100644 --- a/mips/rtl/java/jastrings.inc +++ b/mips/rtl/java/jastrings.inc @@ -79,6 +79,13 @@ begin end; +constructor AnsistringClass.Create(const u: unicodestring); +begin + { for use in Java code } + Create(u,DefaultSystemCodePage); +end; + + constructor AnsistringClass.Create(const a: RawByteString; cp: TSystemCodePage); begin Create(AnsistringClass(a).fdata,system.length(AnsistringClass(a).fdata)-1,cp); diff --git a/mips/rtl/java/java_sysh.inc b/mips/rtl/java/java_sysh.inc index 540e49f8a2..129399a09f 100644 --- a/mips/rtl/java/java_sysh.inc +++ b/mips/rtl/java/java_sysh.inc @@ -1,4 +1,27 @@ -{ Imports for Java packages/classes: java.io.IIOException, java.io.IOException, java.io.Serializable, java.lang.AbstractStringBuilder, java.lang.Appendable, java.lang.AssertionError, java.lang.Boolean, java.lang.Byte, java.lang.CharSequence, java.lang.Character, java.lang.Class, java.lang.Cloneable, java.lang.Comparable, java.lang.Double, java.lang.Enum, java.lang.Error, java.lang.Exception, java.lang.Float, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.IndexOutOfBoundsException, java.lang.Integer, java.lang.Iterable, java.lang.LinkageError, java.lang.Long, java.lang.Math, java.lang.NoSuchMethodException, java.lang.Number, java.lang.Object, java.lang.Readable, java.lang.Runtime, java.lang.RuntimeException, java.lang.Short, java.lang.String, java.lang.StringBuffer, java.lang.StringBuilder, java.lang.System, java.lang.ThreadLocal, java.lang.Throwable, java.lang.UnsupportedOperationException, java.lang.reflect.AccessibleObject, java.lang.reflect.AnnotatedElement, java.lang.reflect.Array, java.lang.reflect.Field, java.lang.reflect.GenericDeclaration, java.lang.reflect.InvocationTargetException, java.lang.reflect.Member, java.lang.reflect.Method, java.lang.reflect.Type, java.math.BigInteger, java.nio.Buffer, java.nio.ByteBuffer, java.nio.CharBuffer, java.nio.charset., java.text.Collator, java.util.AbstractCollection, java.util.AbstractMap, java.util.AbstractSet, java.util.Arrays, java.util.BitSet, java.util.Calendar, java.util.Collection, java.util.Comparator, java.util.EnumSet, java.util.HashMap, java.util.Iterator, java.util.Map, java.util.Set } +{ Imports for Java packages/classes: + java.io.IIOException, java.io.IOException, java.io.Serializable, + java.lang.AbstractStringBuilder, java.lang.Appendable, + java.lang.AssertionError, java.lang.Boolean, java.lang.Byte, + java.lang.CharSequence, java.lang.Character, java.lang.Class, + java.lang.Cloneable, java.lang.Comparable, java.lang.Double, + java.lang.Enum, java.lang.Error, java.lang.Exception, java.lang.Float, + java.lang.IllegalArgumentException, java.lang.IllegalStateException, + java.lang.IndexOutOfBoundsException, java.lang.Integer, java.lang.Iterable, + java.lang.LinkageError, java.lang.Long, java.lang.Math, + java.lang.NoSuchMethodException, java.lang.Number, java.lang.Object, + java.lang.Readable, java.lang.Runtime, java.lang.RuntimeException, + java.lang.Short, java.lang.String, java.lang.StringBuffer, + java.lang.StringBuilder, java.lang.System, java.lang.ThreadLocal, + java.lang.Throwable, java.lang.UnsupportedOperationException, + java.lang.reflect.AccessibleObject, java.lang.reflect.AnnotatedElement, + java.lang.reflect.Array, java.lang.reflect.Field, + java.lang.reflect.GenericDeclaration, java.lang.reflect.InvocationTargetException, + java.lang.reflect.Member, java.lang.reflect.Method, java.lang.reflect.Type, + java.math.BigInteger, java.nio.Buffer, java.nio.ByteBuffer, java.nio.CharBuffer, + java.nio.charset., java.text.Collator, java.util.AbstractCollection, + java.util.AbstractMap, java.util.AbstractSet, java.util.Arrays, java.util.BitSet, + java.util.Calendar, java.util.Collection, java.util.Comparator, java.util.EnumSet, + java.util.HashMap, java.util.Iterator, java.util.Map, java.util.Set } type JLNoSuchMethodException = class; Arr1JLNoSuchMethodException = array of JLNoSuchMethodException; diff --git a/mips/rtl/java/jcompproc.inc b/mips/rtl/java/jcompproc.inc index 49403c5655..68a9d8bb46 100644 --- a/mips/rtl/java/jcompproc.inc +++ b/mips/rtl/java/jcompproc.inc @@ -376,7 +376,7 @@ procedure fpc_variant_init(var v: tvardata);compilerproc; procedure fpc_variant_clear(var v: tvardata);compilerproc; {$ifdef FPC_VARIANTCOPY_FIXED} procedure fpc_variant_copy(var d: tvardata; const s : tvardata);compilerproc; -procedure fpc_variant_copy_overwrite(const source: tvardata; var dest : tvardata);compilerproc; +procedure fpc_variant_copy_overwrite(constref source: tvardata; var dest : tvardata);compilerproc; {$else FPC_VARIANTCOPY_FIXED} procedure fpc_variant_copy(d,s : pointer);compilerproc; procedure fpc_variant_copy_overwrite(source, dest : pointer);compilerproc; diff --git a/mips/rtl/java/jsystemh.inc b/mips/rtl/java/jsystemh.inc index 583e93b440..e21e2c6bc7 100644 --- a/mips/rtl/java/jsystemh.inc +++ b/mips/rtl/java/jsystemh.inc @@ -169,7 +169,7 @@ Function Random: extended; Procedure Randomize; {$endif FPC_HAS_FEATURE_RANDOM} -{$ifdef FPC_HAS_INTERNAL_ABS_LONG and (defined(cpui386) or defined(cpux86_64) or defined(cpupowerpc))} +{$ifdef FPC_HAS_INTERNAL_ABS_LONG} {$define FPC_SYSTEM_HAS_ABS_LONGINT} Function abs(l:longint):longint;[internproc:fpc_in_abs_long]; {$else FPC_HAS_INTERNAL_ABS_LONG} @@ -591,15 +591,15 @@ Procedure getdir(drivenr:byte;var dir:ansistring); //function get_frame:pointer;[INTERNPROC:fpc_in_get_frame]; (* // still defined externally -function get_caller_addr(framebp:pointer):pointer;[INTERNPROC:fpc_in_get_caller_addr]; -function get_caller_frame(framebp:pointer):pointer;[INTERNPROC:fpc_in_get_caller_frame]; +function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;[INTERNPROC:fpc_in_get_caller_addr]; +function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;[INTERNPROC:fpc_in_get_caller_frame]; *) {$ELSE} function get_frame:pointer;{$ifdef SYSTEMINLINE}inline;{$endif} {$ENDIF} (* -function get_caller_addr(framebp:pointer):pointer; -function get_caller_frame(framebp:pointer):pointer; +function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer; +function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer; *) //Function IOResult:Word; diff --git a/mips/rtl/jvm/jvm.inc b/mips/rtl/jvm/jvm.inc index 43b18fddd9..a588dc81e5 100644 --- a/mips/rtl/jvm/jvm.inc +++ b/mips/rtl/jvm/jvm.inc @@ -25,7 +25,7 @@ Procedure SysInitFPU;{$ifdef SYSTEMINLINE}inline;{$endif} begin softfloat_exception_mask:=float_flag_underflow or float_flag_inexact or float_flag_denormal; end; - + {$define FPC_SYSTEM_HAS_SYSRESETFPU} Procedure SysResetFPU;{$ifdef SYSTEMINLINE}inline;{$endif} begin @@ -49,14 +49,14 @@ function get_frame:pointer; {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR} -function get_caller_addr(framebp:pointer):pointer; +function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer; begin result:=nil; end; {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME} -function get_caller_frame(framebp:pointer):pointer; +function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer; begin result:=nil; end; diff --git a/mips/rtl/linux/Makefile b/mips/rtl/linux/Makefile index eefecc7e17..ae78a02681 100644 --- a/mips/rtl/linux/Makefile +++ b/mips/rtl/linux/Makefile @@ -1,5 +1,5 @@ # -# Don't edit, this file is generated by FPCMake Version 2.0.0 [2012/05/29] +# Don't edit, this file is generated by FPCMake Version 2.0.0 [2012/07/07] # default: all MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux jvm-java jvm-android @@ -3214,6 +3214,11 @@ strings$(PPUEXT) : $(INC)/strings.pp $(INC)/stringsi.inc\ unix$(PPUEXT) : $(UNIXINC)/unix.pp strings$(PPUEXT) baseunix$(PPUEXT) $(INC)/textrec.inc $(INC)/filerec.inc \ unxconst.inc $(UNIXINC)/timezone.inc $(SYSTEMUNIT)$(PPUEXT) \ unxfunc.inc + $(COMPILER) $(UNIXINC)/unix.pp +syscall$(PPUEXT) : $(UNIXINC)/syscall.pp $(ARCH)/syscallh.inc $(ARCH)/sysnr.inc $(SYSTEMUNIT)$(PPUEXT) + $(COMPILER) $(UNIXINC)/syscall.pp +unixutil$(PPUEXT) : $(UNIXINC)/unixutil.pp $(INC)/textrec.inc $(INC)/filerec.inc $(SYSTEMUNIT)$(PPUEXT) + $(COMPILER) $(UNIXINC)/unixutil.pp unixtype$(PPUEXT) : $(UNIXINC)/unixtype.pp ptypes.inc $(UNIXINC)/ctypes.inc $(SYSTEMUNIT)$(PPUEXT) $(COMPILER) $(UNIXINC)/unixtype.pp baseunix$(PPUEXT) : errno.inc ptypes.inc $(UNIXINC)/ctypes.inc \ @@ -3221,7 +3226,9 @@ baseunix$(PPUEXT) : errno.inc ptypes.inc $(UNIXINC)/ctypes.inc \ bunxsysc.inc $(ARCH)/syscallh.inc $(ARCH)/sysnr.inc \ ostypes.inc osmacro.inc $(UNIXINC)/gensigset.inc \ $(UNIXINC)/genfuncs.inc $(SYSTEMUNIT)$(PPUEXT) -ports$(PPUEXT) : ports.pp unix$(PPUEXT) objpas$(PPUEXT) + $(COMPILER) $(UNIXINC)/baseunix.pp +ports$(PPUEXT) : $(UNIXINC)/ports.pp unix$(PPUEXT) objpas$(PPUEXT) + $(COMPILER) $(UNIXINC)/ports.pp dl$(PPUEXT) : $(UNIXINC)/dl.pp $(SYSTEMUNIT)$(PPUEXT) $(COMPILER) $(UNIXINC)/dl.pp dynlibs$(PPUEXT) : $(INC)/dynlibs.pas $(UNIXINC)/dynlibs.inc dl$(PPUEXT) objpas$(PPUEXT) @@ -3284,6 +3291,8 @@ cpu$(PPUEXT) : $(PROCINC)/cpu.pp $(SYSTEMUNIT)$(PPUEXT) endif mmx$(PPUEXT) : $(PROCINC)/mmx.pp cpu$(PPUEXT) $(SYSTEMUNIT)$(PPUEXT) $(COMPILER) $(PROCINC)/mmx.pp +x86$(PPUEXT) : $(UNIXINC)/x86.pp baseunix$(PPUEXT) syscall$(PPUEXT) $(SYSTEMUNIT)$(PPUEXT) + $(COMPILER) $(UNIXINC)/x86.pp getopts$(PPUEXT) : $(INC)/getopts.pp $(SYSTEMUNIT)$(PPUEXT) $(COMPILER) $(INC)/getopts.pp heaptrc$(PPUEXT) : $(INC)/heaptrc.pp $(SYSTEMUNIT)$(PPUEXT) diff --git a/mips/rtl/linux/Makefile.fpc b/mips/rtl/linux/Makefile.fpc index 8f27da22e3..fcf56b0fe0 100644 --- a/mips/rtl/linux/Makefile.fpc +++ b/mips/rtl/linux/Makefile.fpc @@ -187,6 +187,13 @@ strings$(PPUEXT) : $(INC)/strings.pp $(INC)/stringsi.inc\ unix$(PPUEXT) : $(UNIXINC)/unix.pp strings$(PPUEXT) baseunix$(PPUEXT) $(INC)/textrec.inc $(INC)/filerec.inc \ unxconst.inc $(UNIXINC)/timezone.inc $(SYSTEMUNIT)$(PPUEXT) \ unxfunc.inc + $(COMPILER) $(UNIXINC)/unix.pp + +syscall$(PPUEXT) : $(UNIXINC)/syscall.pp $(ARCH)/syscallh.inc $(ARCH)/sysnr.inc $(SYSTEMUNIT)$(PPUEXT) + $(COMPILER) $(UNIXINC)/syscall.pp + +unixutil$(PPUEXT) : $(UNIXINC)/unixutil.pp $(INC)/textrec.inc $(INC)/filerec.inc $(SYSTEMUNIT)$(PPUEXT) + $(COMPILER) $(UNIXINC)/unixutil.pp unixtype$(PPUEXT) : $(UNIXINC)/unixtype.pp ptypes.inc $(UNIXINC)/ctypes.inc $(SYSTEMUNIT)$(PPUEXT) $(COMPILER) $(UNIXINC)/unixtype.pp @@ -196,8 +203,10 @@ baseunix$(PPUEXT) : errno.inc ptypes.inc $(UNIXINC)/ctypes.inc \ bunxsysc.inc $(ARCH)/syscallh.inc $(ARCH)/sysnr.inc \ ostypes.inc osmacro.inc $(UNIXINC)/gensigset.inc \ $(UNIXINC)/genfuncs.inc $(SYSTEMUNIT)$(PPUEXT) + $(COMPILER) $(UNIXINC)/baseunix.pp -ports$(PPUEXT) : ports.pp unix$(PPUEXT) objpas$(PPUEXT) +ports$(PPUEXT) : $(UNIXINC)/ports.pp unix$(PPUEXT) objpas$(PPUEXT) + $(COMPILER) $(UNIXINC)/ports.pp dl$(PPUEXT) : $(UNIXINC)/dl.pp $(SYSTEMUNIT)$(PPUEXT) $(COMPILER) $(UNIXINC)/dl.pp @@ -303,6 +312,9 @@ endif mmx$(PPUEXT) : $(PROCINC)/mmx.pp cpu$(PPUEXT) $(SYSTEMUNIT)$(PPUEXT) $(COMPILER) $(PROCINC)/mmx.pp +x86$(PPUEXT) : $(UNIXINC)/x86.pp baseunix$(PPUEXT) syscall$(PPUEXT) $(SYSTEMUNIT)$(PPUEXT) + $(COMPILER) $(UNIXINC)/x86.pp + getopts$(PPUEXT) : $(INC)/getopts.pp $(SYSTEMUNIT)$(PPUEXT) $(COMPILER) $(INC)/getopts.pp diff --git a/mips/rtl/linux/errno-mips.inc b/mips/rtl/linux/errno-mips.inc new file mode 100644 index 0000000000..7d605ab465 --- /dev/null +++ b/mips/rtl/linux/errno-mips.inc @@ -0,0 +1,147 @@ +{ File generated by ../unix/scripts/check_errno.sh + generated on "Linux 2.6.27.1 mips64" machine +List of missing system error number found in +/usr/include/asm-generic/errno-base.h +/usr/include/asm/errno.h +/usr/include/bits/errno.h +/usr/include/bits/wordsize.h +/usr/include/errno.h +/usr/include/features.h +/usr/include/gnu/stubs.h +/usr/include/linux/errno.h +/usr/include/sys/cdefs.h +} + ESysEPERM = 1; { Operation not permitted } + ESysENOENT = 2; { No such file or directory } + ESysESRCH = 3; { No such process } + ESysEINTR = 4; { Interrupted system call } + ESysEIO = 5; { I/O error } + ESysENXIO = 6; { No such device or address } + ESysE2BIG = 7; { Argument list too long } + ESysENOEXEC = 8; { Exec format error } + ESysEBADF = 9; { Bad file number } + ESysECHILD = 10; { No child processes } + ESysEAGAIN = 11; { Try again } + ESysENOMEM = 12; { Out of memory } + ESysEACCES = 13; { Permission denied } + ESysEFAULT = 14; { Bad address } + ESysENOTBLK = 15; { Block device required } + ESysEBUSY = 16; { Device or resource busy } + ESysEEXIST = 17; { File exists } + ESysEXDEV = 18; { Cross-device link } + ESysENODEV = 19; { No such device } + ESysENOTDIR = 20; { Not a directory } + ESysEISDIR = 21; { Is a directory } + ESysEINVAL = 22; { Invalid argument } + ESysENFILE = 23; { File table overflow } + ESysEMFILE = 24; { Too many open files } + ESysENOTTY = 25; { Not a typewriter } + ESysETXTBSY = 26; { Text file busy } + ESysEFBIG = 27; { File too large } + ESysENOSPC = 28; { No space left on device } + ESysESPIPE = 29; { Illegal seek } + ESysEROFS = 30; { Read-only file system } + ESysEMLINK = 31; { Too many links } + ESysEPIPE = 32; { Broken pipe } + ESysEDOM = 33; { Math argument out of domain of func } + ESysERANGE = 34; { Math result not representable } + ESysENOMSG = 35; { No message of desired type } + ESysEIDRM = 36; { Identifier removed } + ESysECHRNG = 37; { Channel number out of range } + ESysEL2NSYNC = 38; { Level 2 not synchronized } + ESysEL3HLT = 39; { Level 3 halted } + ESysEL3RST = 40; { Level 3 reset } + ESysELNRNG = 41; { Link number out of range } + ESysEUNATCH = 42; { Protocol driver not attached } + ESysENOCSI = 43; { No CSI structure available } + ESysEL2HLT = 44; { Level 2 halted } + ESysEDEADLK = 45; { Resource deadlock would occur } + ESysENOLCK = 46; { No record locks available } + ESysEBADE = 50; { Invalid exchange } + ESysEBADR = 51; { Invalid request descriptor } + ESysEXFULL = 52; { Exchange full } + ESysENOANO = 53; { No anode } + ESysEBADRQC = 54; { Invalid request code } + ESysEBADSLT = 55; { Invalid slot } + ESysEDEADLOCK = 56; { File locking deadlock error } + ESysEBFONT = 59; { Bad font file format } + ESysENOSTR = 60; { Device not a stream } + ESysENODATA = 61; { No data available } + ESysETIME = 62; { Timer expired } + ESysENOSR = 63; { Out of streams resources } + ESysENONET = 64; { Machine is not on the network } + ESysENOPKG = 65; { Package not installed } + ESysEREMOTE = 66; { Object is remote } + ESysENOLINK = 67; { Link has been severed } + ESysEADV = 68; { Advertise error } + ESysESRMNT = 69; { Srmount error } + ESysECOMM = 70; { Communication error on send } + ESysEPROTO = 71; { Protocol error } + ESysEDOTDOT = 73; { RFS specific error } + ESysEMULTIHOP = 74; { Multihop attempted } + ESysEBADMSG = 77; { Not a data message } + ESysENAMETOOLONG = 78; { File name too long } + ESysEOVERFLOW = 79; { Value too large for defined data type } + ESysENOTUNIQ = 80; { Name not unique on network } + ESysEBADFD = 81; { File descriptor in bad state } + ESysEREMCHG = 82; { Remote address changed } + ESysELIBACC = 83; { Can not access a needed shared library } + ESysELIBBAD = 84; { Accessing a corrupted shared library } + ESysELIBSCN = 85; { .lib section in a.out corrupted } + ESysELIBMAX = 86; { Attempting to link in too many shared libraries } + ESysELIBEXEC = 87; { Cannot exec a shared library directly } + ESysEILSEQ = 88; { Illegal byte sequence } + ESysENOSYS = 89; { Function not implemented } + ESysELOOP = 90; { Too many symbolic links encountered } + ESysERESTART = 91; { Interrupted system call should be restarted } + ESysESTRPIPE = 92; { Streams pipe error } + ESysENOTEMPTY = 93; { Directory not empty } + ESysEUSERS = 94; { Too many users } + ESysENOTSOCK = 95; { Socket operation on non-socket } + ESysEDESTADDRREQ = 96; { Destination address required } + ESysEMSGSIZE = 97; { Message too long } + ESysEPROTOTYPE = 98; { Protocol wrong type for socket } + ESysENOPROTOOPT = 99; { Protocol not available } + ESysEPROTONOSUPPORT = 120; { Protocol not supported } + ESysESOCKTNOSUPPORT = 121; { Socket type not supported } + ESysEOPNOTSUPP = 122; { Operation not supported on transport endpoint } + ESysEPFNOSUPPORT = 123; { Protocol family not supported } + ESysEAFNOSUPPORT = 124; { Address family not supported by protocol } + ESysEADDRINUSE = 125; { Address already in use } + ESysEADDRNOTAVAIL = 126; { Cannot assign requested address } + ESysENETDOWN = 127; { Network is down } + ESysENETUNREACH = 128; { Network is unreachable } + ESysENETRESET = 129; { Network dropped connection because of reset } + ESysECONNABORTED = 130; { Software caused connection abort } + ESysECONNRESET = 131; { Connection reset by peer } + ESysENOBUFS = 132; { No buffer space available } + ESysEISCONN = 133; { Transport endpoint is already connected } + ESysENOTCONN = 134; { Transport endpoint is not connected } + ESysEUCLEAN = 135; { Structure needs cleaning } + ESysENOTNAM = 137; { Not a XENIX named type file } + ESysENAVAIL = 138; { No XENIX semaphores available } + ESysEISNAM = 139; { Is a named type file } + ESysEREMOTEIO = 140; { Remote I/O error } + ESysEINIT = 141; { Reserved } + ESysEREMDEV = 142; { Error 142 } + ESysESHUTDOWN = 143; { Cannot send after transport endpoint shutdown } + ESysETOOMANYREFS = 144; { Too many references: cannot splice } + ESysETIMEDOUT = 145; { Connection timed out } + ESysECONNREFUSED = 146; { Connection refused } + ESysEHOSTDOWN = 147; { Host is down } + ESysEHOSTUNREACH = 148; { No route to host } + ESysEWOULDBLOCK = EsysEAGAIN; { Operation would block } + ESysEALREADY = 149; { Operation already in progress } + ESysEINPROGRESS = 150; { Operation now in progress } + ESysESTALE = 151; { Stale NFS file handle } + ESysECANCELED = 158; { AIO operation canceled } + ESysENOMEDIUM = 159; { No medium found } + ESysEMEDIUMTYPE = 160; { Wrong medium type } + ESysENOKEY = 161; { Required key not available } + ESysEKEYEXPIRED = 162; { Key has expired } + ESysEKEYREVOKED = 163; { Key has been revoked } + ESysEKEYREJECTED = 164; { Key was rejected by service } + ESysEOWNERDEAD = 165; { Owner died } + ESysENOTRECOVERABLE = 166; { State not recoverable } + ESysERFKILL = 167; { Operation not possible due to RF-kill } + ESysEDQUOT = 1133; { Quota exceeded } diff --git a/mips/rtl/linux/errno.inc b/mips/rtl/linux/errno.inc index 21819b9dd4..f1ccf4b5b4 100644 --- a/mips/rtl/linux/errno.inc +++ b/mips/rtl/linux/errno.inc @@ -24,6 +24,11 @@ const {$i errno-sparc.inc} {$endif CPUSPARC} +{$ifdef CPUMIPS} +{$define FPC_HAS_ESYS} +{$i errno-mips.inc} +{$endif CPUMIPS} + {$ifndef FPC_HAS_ESYS} ESysEPERM = 1; { Operation not permitted } ESysENOENT = 2; { No such file or directory } diff --git a/mips/rtl/linux/mips/cprt0.as b/mips/rtl/linux/mips/cprt0.as index e69de29bb2..2d9902569f 100644 --- a/mips/rtl/linux/mips/cprt0.as +++ b/mips/rtl/linux/mips/cprt0.as @@ -0,0 +1,149 @@ +/* Startup code compliant to the ELF Mips ABI. + Copyright (C) 1995, 1997, 2000, 2001, 2002, 2003, 2004 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file with other + programs, and to distribute those programs without any restriction + coming from the use of this file. (The GNU Lesser General Public + License restrictions do apply in other respects; for example, they + cover modification of the file, and distribution when not linked + into another program.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* This is the canonical entry point, usually the first thing in the text + segment. The SVR4/Mips ABI (pages 3-31, 3-32) says that when the entry + point runs, most registers' values are unspecified, except for: + + v0 ($2) Contains a function pointer to be registered with `atexit'. + This is how the dynamic linker arranges to have DT_FINI + functions called for shared libraries that have been loaded + before this code runs. + + sp ($29) The stack contains the arguments and environment: + 0(%esp) argc + 4(%esp) argv[0] + ... + (4*argc)(%esp) NULL + (4*(argc+1))(%esp) envp[0] + ... + NULL + ra ($31) The return address register is set to zero so that programs + that search backword through stack frames recognize the last + stack frame. +*/ + + +/* We need to call: + __libc_start_main (int (*main) (int, char **, char **), int argc, + char **argv, void (*init) (void), void (*fini) (void), + void (*rtld_fini) (void), void *stack_end) +*/ + .text + .globl __start + .type __start,@function +__start: +.globl _start + .type _start,@function +_start: + .ent _start + + + .set noreorder + move $0, $31 + bal 10f + nop + 10: + .cpload $31 + move $31, $0 + .set reorder + /* Setup GP correctly if we're non-PIC. */ + la $28,_gp + + la $4, main /* main */ + lw $5, 0($29) /* argc */ + addiu $6, $29, 4 /* argv */ + /* store argc */ + lw $t0,0($29) + lui $t1,%hi(operatingsystem_parameter_argc) + sw $t0,%lo(operatingsystem_parameter_argc)($t1) + + /* store argv */ + addiu $t1,$29,4 + lui $t2,%hi(operatingsystem_parameter_argv) + sw $t1,%lo(operatingsystem_parameter_argv)($t2) + + /* store envp */ + addiu $t2,$t0,1 + sll $t2,$t2,0x2 + addu $t2,$t2,$t1 + lui $t3,%hi(operatingsystem_parameter_envp) + sw $t2,%lo(operatingsystem_parameter_envp)($t3) + + /* Allocate space on the stack for seven arguments (o32 only) + and make sure the stack is aligned to double words (8 bytes) + on o32 and quad words (16 bytes) on n32 and n64. */ + and $29, -2 * 4 + subu $29, 32 + + lw $7,%got(__libc_csu_init)($gp) /* init */ + lw $8,%got(__libc_csu_fini)($gp) /* fini */ + + sw $8, 16($29) /* fini */ + sw $2, 20($29) /* rtld_fini */ + sw $29, 24($29) /* stack_end */ + + lw $t9,%got(__libc_start_main)($gp) + jalr $t9 + .end _start + .size _start, . - _start +/* Crash if somehow it does return. */ + .globl _haltproc + .ent _haltproc + .type _haltproc,@function +_haltproc: +hlt: + li $v0,4001 + syscall + b hlt + .end _haltproc + +/* Define a symbol for the first piece of initialized data. */ + .data + .globl __data_start +__data_start: + .long 0 + .weak data_start + data_start = __data_start + + .comm __stkptr,4 + .comm __dl_fini,4 + + .comm operatingsystem_parameter_envp,4 + .comm operatingsystem_parameter_argc,4 + .comm operatingsystem_parameter_argv,4 + diff --git a/mips/rtl/linux/mips/dllprt0.as b/mips/rtl/linux/mips/dllprt0.as index e69de29bb2..c6db79ac33 100644 --- a/mips/rtl/linux/mips/dllprt0.as +++ b/mips/rtl/linux/mips/dllprt0.as @@ -0,0 +1 @@ +.include "mips/prt0.as" diff --git a/mips/rtl/linux/mips/gprt0.as b/mips/rtl/linux/mips/gprt0.as index e69de29bb2..c6db79ac33 100644 --- a/mips/rtl/linux/mips/gprt0.as +++ b/mips/rtl/linux/mips/gprt0.as @@ -0,0 +1 @@ +.include "mips/prt0.as" diff --git a/mips/rtl/linux/mips/prt0.as b/mips/rtl/linux/mips/prt0.as index 88fc6e28c7..0bd2c63333 100644 --- a/mips/rtl/linux/mips/prt0.as +++ b/mips/rtl/linux/mips/prt0.as @@ -27,7 +27,7 @@ _dynamic_start: nop .end _dynamic_start - .size _dynamic_start, .-_start + .size _dynamic_start, .-_dynamic_start .align 4 .global _start @@ -54,6 +54,8 @@ _dynamic_start: _start: /* load fp */ move $s8,$sp + lui $at,%hi(__stkptr) + sw $s8,%lo(__stkptr)($at) /* align stack */ li $at,-8 @@ -82,8 +84,10 @@ _start: sll $a2,$a2,0x2 addu $a2,$a2,$a1 lui $a3,%hi(operatingsystem_parameter_envp) - jal PASCALMAIN sw $a2,%lo(operatingsystem_parameter_envp)($a3) + lui $t9,%hi(PASCALMAIN) + addiu $t9,$t9,%lo(PASCALMAIN) + jalr $t9 nop b _haltproc nop diff --git a/mips/rtl/linux/mips/sighnd.inc b/mips/rtl/linux/mips/sighnd.inc index ae71d813c4..2a782e21f1 100644 --- a/mips/rtl/linux/mips/sighnd.inc +++ b/mips/rtl/linux/mips/sighnd.inc @@ -15,10 +15,11 @@ **********************************************************************} -procedure SignalToRunerror(sig : longint; SigInfo: PSigInfo; SigContext: PSigContext);cdecl; +procedure SignalToRunerror(sig : longint; SigInfo: PSigInfo; UContext: PUContext);cdecl; var res : word; addr : pointer; + frame : pointer; begin res:=0; addr:=nil; @@ -27,11 +28,12 @@ begin begin addr := siginfo^._sifields._sigfault._addr; res := 207; + case siginfo^.si_code of FPE_INTDIV: res:=200; FPE_INTOVF: - res:=205; + res:=215; FPE_FLTDIV: res:=200; FPE_FLTOVF: @@ -57,5 +59,32 @@ begin reenable_signal(sig); { give runtime error at the position where the signal was raised } if res<>0 then - HandleErrorAddrFrame(res,addr,nil); + begin + if assigned(UContext) then + begin + frame:=pointer(ptruint(UContext^.uc_mcontext.sigc_regs[29])); { stack pointer } + addr:=pointer(ptruint(UContext^.uc_mcontext.sigc_pc)); { program counter } + if sig=SIGFPE then + begin + { Clear FPU exception bits } + UContext^.uc_mcontext.sigc_fpc_csr := UContext^.uc_mcontext.sigc_fpc_csr + and not (fpu_cause_mask or fpu_flags_mask); + end; + { Change $a1, $a2, $a3 and sig_pc to HandleErrorAddrFrame parameters } + UContext^.uc_mcontext.sigc_regs[4]:=res; + UContext^.uc_mcontext.sigc_regs[5]:=ptrint(addr); + UContext^.uc_mcontext.sigc_regs[6]:=ptrint(frame); + UContext^.uc_mcontext.sigc_pc:=ptrint(@HandleErrorAddrFrame); + { Let the system call HandleErrorAddrFrame } + exit; + end + else + begin + frame:=nil; + addr:=nil; + end; + if sig=SIGFPE then + set_fsr(get_fsr and not (fpu_cause_mask or fpu_flags_mask)); + HandleErrorAddrFrame(res,addr,frame); + end; end; diff --git a/mips/rtl/linux/mips/sighndh.inc b/mips/rtl/linux/mips/sighndh.inc index e3cfd870f3..ce4ffdee67 100644 --- a/mips/rtl/linux/mips/sighndh.inc +++ b/mips/rtl/linux/mips/sighndh.inc @@ -25,22 +25,72 @@ type ins : array[0..7] of longint; end; +(* MIPS OABI32 structure +struct sigcontext { + unsigned int sc_regmask; + unsigned int sc_status; + unsigned long long sc_pc; + unsigned long long sc_regs[32]; + unsigned long long sc_fpregs[32]; + unsigned int sc_ownedfp; + unsigned int sc_fpc_csr; + unsigned int sc_fpc_eir; + unsigned int sc_used_math; + unsigned int sc_dsp; + unsigned long long sc_mdhi; + unsigned long long sc_mdlo; + unsigned long sc_hi1; + unsigned long sc_lo1; + unsigned long sc_hi2; + unsigned long sc_lo2; + unsigned long sc_hi3; + unsigned long sc_lo3; +}; +typedef struct ucontext + { + unsigned long int uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + mcontext_t uc_mcontext; + __sigset_t uc_sigmask; + } ucontext_t; + + *) + FPReg = record + case byte of + 0 : (fp_dreg : double;); + 1 : (fp_reg : single; + fp_pad : cint; ); + end; + PSigContext = ^TSigContext; TSigContext = record - sigc_onstack, { state to restore } - sigc_mask, { sigmask to restore } - sigc_sp, { stack pointer } - sigc_pc, { program counter } - sigc_npc, { next program counter } - sigc_psr, { for condition codes etc } - sigc_g1, { User uses these two registers } - sigc_o0, { within the trampoline code. } - { Now comes information regarding the users window set - * at the time of the signal. } - sigc_oswins : longint; { outstanding windows } - { stack ptrs for each regwin buf } - sigc_spbuf : array[0..__SUNOS_MAXWIN-1] of pchar; - { Windows to restore after signal } - sigc_wbuf : array[0..__SUNOS_MAXWIN] of twbuf; + sigc_regmask, + sigc_status: cuint; + sigc_pc : culonglong; + sigc_regs : array[0..31] of culonglong; + sigc_fpregs : array[0..31] of fpreg; + sigc_fpc_csr, sigc_fpc_eir : cuint; + sigc_used_math : cuint; + sigc_dsp : cuint; + sigc_mdhi, sigc_mdlo : culonglong; + sigc_hi1,sigc_lo1, + sigc_hi2,sigc_lo2, + sigc_hi3,sigc_lo3 : culong; + end; + + TStack = record + ss_sp : pointer; + ss_size : size_t; + ss_flags : cint; + end; + + PUContext = ^TUContext; + TUContext = record + uc_flags : culong; + uc_link : PUContext; + uc_stack : TStack; + uc_mcontext : TSigContext; + uc_sigmask : TSigSet; end; diff --git a/mips/rtl/linux/mips/syscall.inc b/mips/rtl/linux/mips/syscall.inc index 677a20a93a..bc8c1bacce 100644 --- a/mips/rtl/linux/mips/syscall.inc +++ b/mips/rtl/linux/mips/syscall.inc @@ -47,7 +47,7 @@ asm addiu $4,$4,%lo(errno) jalr $8 nop - lw $8,-4($fp) + lw $8,temp sw $8,0($2) .LFailed: li $2,-1 @@ -225,7 +225,7 @@ asm move $a0,$a1 move $a1,$a2 move $a2,$a3 - lw $a3,16($fp) + lw $a3,param4 syscall nop beq $7,$0,.LDone @@ -266,10 +266,10 @@ asm move $a0,$a1 move $a1,$a2 move $a2,$a3 - lw $a3,16($fp) - lw $t0,20($fp) + lw $a3,param4 + lw $t0,param5 sw $t0,16($sp) - + syscall nop beq $7,$0,.LDone @@ -311,10 +311,10 @@ asm move $a0,$a1 move $a1,$a2 move $a2,$a3 - lw $a3,16($fp) - lw $t0,20($fp) + lw $a3,param4 + lw $t0,param5 sw $t0,16($sp) - lw $t0,24($fp) + lw $t0,param6 sw $t0,20($sp) syscall nop diff --git a/mips/rtl/linux/ossysc.inc b/mips/rtl/linux/ossysc.inc index f7040b7aa5..2ff2825b35 100644 --- a/mips/rtl/linux/ossysc.inc +++ b/mips/rtl/linux/ossysc.inc @@ -319,7 +319,14 @@ begin end; end; {$endif} - Fpsigaction:=do_syscall(syscall_nr_rt_sigaction,TSysParam(sig),TSysParam(new_action),TSysParam(old_action),TSysParam(8)); + Fpsigaction:=do_syscall(syscall_nr_rt_sigaction,TSysParam(sig), + TSysParam(new_action),TSysParam(old_action), + {$ifdef cpumips} + TSysParam(16{should be wordsinsigset}) + {$else not cpumips} + TSysParam(8) + {$endif not cpumips} + ); {$endif cpusparc} end; @@ -569,7 +576,14 @@ function FPSigProcMask(how:cint;nset : psigset;oset : psigset):cint; [public, al } begin - FPsigprocmask:=do_syscall(syscall_nr_rt_sigprocmask,TSysParam(how),TSysParam(nset),TSysParam(oset),TSysParam(8)); + FPsigprocmask:=do_syscall(syscall_nr_rt_sigprocmask,TSysParam(how), + TSysParam(nset),TSysParam(oset), +{$ifdef CPUMIPS} + TSysParam(16) +{$else not CPUMIPS} + TSysParam(8) +{$endif not CPUMIPS} + ); end; Function FpNanoSleep(req : ptimespec;rem : ptimespec):cint; [public, alias : 'FPC_SYSC_NANOSLEEP']; diff --git a/mips/rtl/linux/ostypes.inc b/mips/rtl/linux/ostypes.inc index a0bcfa919b..b29a618a72 100644 --- a/mips/rtl/linux/ostypes.inc +++ b/mips/rtl/linux/ostypes.inc @@ -245,7 +245,20 @@ CONST O_DIRECTORY = $10000; O_NOFOLLOW = $20000; O_DIRECT = $100000; -{$else cpusparc} +{$else : not cpusparc} +{$ifdef cpumips} + O_CREAT = $100; + O_EXCL = $400; + O_NOCTTY = $800; + O_TRUNC = $200; + O_APPEND = $8; + O_NONBLOCK = $80; + O_NDELAY = O_NONBLOCK; + O_SYNC = $10; + O_DIRECT = $8000; + O_DIRECTORY = $10000; + O_NOFOLLOW = $20000; +{$else : not cpumips} O_CREAT = $40; O_EXCL = $80; O_NOCTTY = $100; @@ -257,7 +270,8 @@ CONST O_DIRECT = $4000; O_DIRECTORY = $10000; O_NOFOLLOW = $20000; -{$endif cpusparc} +{$endif not cpumips} +{$endif not cpusparc} {$if defined(cpuarm) or defined(cpualpha) or defined(cpublackfin) or defined(cpum68k)} O_LARGEFILE = $20000; diff --git a/mips/rtl/linux/ptypes.inc b/mips/rtl/linux/ptypes.inc index a483ed5cf8..14e6c181b6 100644 --- a/mips/rtl/linux/ptypes.inc +++ b/mips/rtl/linux/ptypes.inc @@ -21,7 +21,7 @@ { Introduced defines - fs32bit, should be on if libc only supports sizeof(off_t)=4 - we assume one typically compiles C applications with + we assume one typically compiles C applications with #define _FILE_OFFSET_BITS 64 All three tested systems (PPC,Alpha,2x i386) gave the same POSIX limits, @@ -30,6 +30,33 @@ and all three 32-bit systems returned completely identical types too introduction) } +{$ifdef CPUMIPS} +{$define USE_PTHREAD_SIZEOF} +{$ifdef CPU64} +const + __SIZEOF_PTHREAD_ATTR_T = 56; + __SIZEOF_PTHREAD_MUTEX_T = 40; + __SIZEOF_PTHREAD_MUTEXATTR_T = 4; + __SIZEOF_PTHREAD_COND_T = 48; + __SIZEOF_PTHREAD_CONDATTR_T = 4; + __SIZEOF_PTHREAD_RWLOCK_T = 56; + __SIZEOF_PTHREAD_RWLOCKATTR_T = 8; + __SIZEOF_PTHREAD_BARRIER_T = 32; + __SIZEOF_PTHREAD_BARRIERATTR_T = 4; +{$else : not CPU64, i.e. CPU32} +const + __SIZEOF_PTHREAD_ATTR_T = 36; + __SIZEOF_PTHREAD_MUTEX_T = 24; + __SIZEOF_PTHREAD_MUTEXATTR_T = 4; + __SIZEOF_PTHREAD_COND_T = 48; + __SIZEOF_PTHREAD_CONDATTR_T = 4; + __SIZEOF_PTHREAD_RWLOCK_T = 32; + __SIZEOF_PTHREAD_RWLOCKATTR_T = 8; + __SIZEOF_PTHREAD_BARRIER_T = 20; + __SIZEOF_PTHREAD_BARRIERATTR_T = 4; +{$endif CPU32} +{$endif MIPS} + {$I ctypes.inc} {$packrecords c} @@ -119,7 +146,7 @@ Type pUid = ^uid_t; TGid = gid_t; pGid = ^gid_t; - + TIOCtlRequest = cInt; @@ -177,7 +204,7 @@ Type 0: (__wch: wint_t); 1: (__wchb: array[0..3] of char); end; - + mbstate_t = record __count: cint; __value: mbstate_value_t; @@ -190,7 +217,26 @@ Type __sched_priority: cint; end; + { MIPS32 size of unions + __SIZEOF_PTHREAD_ATTR_T = 36; + __SIZEOF_PTHREAD_MUTEX_T = 24; + __SIZEOF_PTHREAD_MUTEXATTR_T = 4; + __SIZEOF_PTHREAD_COND_T = 48; + __SIZEOF_PTHREAD_CONDATTR_T = 4; + __SIZEOF_PTHREAD_RWLOCK_T = 32; + __SIZEOF_PTHREAD_RWLOCKATTR_T = 8; + __SIZEOF_PTHREAD_BARRIER_T = 20; + __SIZEOF_PTHREAD_BARRIERATTR_T = 4; } + pthread_attr_t = record + {$ifdef USE_PTHREAD_SIZEOF} + case byte of + 0 : ( + __size : array[0..__SIZEOF_PTHREAD_ATTR_T-1] of char; + __align : clong; + ); + 1 : ( + {$endif} __detachstate: cint; __schedpolicy: cint; __schedparam: sched_param; @@ -200,6 +246,9 @@ Type __stackaddr_set: cint; __stackaddr: pointer; __stacksize: size_t; + {$ifdef USE_PTHREAD_SIZEOF} + ); + {$endif} end; _pthread_fastlock = record @@ -208,26 +257,70 @@ Type end; pthread_mutex_t = record + {$ifdef USE_PTHREAD_SIZEOF} + case byte of + 0 : ( + __size : array[0..__SIZEOF_PTHREAD_MUTEX_T-1] of char; + __align : clong; + ); + 1 : ( + {$endif} __m_reserved: cint; __m_count: cint; __m_owner: pointer; __m_kind: cint; __m_lock: _pthread_fastlock; + {$ifdef USE_PTHREAD_SIZEOF} + ); + {$endif} end; pthread_mutexattr_t = record + {$ifdef USE_PTHREAD_SIZEOF} + case byte of + 0 : ( + __size : array[0..__SIZEOF_PTHREAD_MUTEXATTR_T-1] of char; + __align : clong; + ); + 1 : ( + {$endif} __mutexkind: cint; + {$ifdef USE_PTHREAD_SIZEOF} + ); + {$endif} end; pthread_cond_t = record + {$ifdef USE_PTHREAD_SIZEOF} + case byte of + 0 : ( + __size : array[0..__SIZEOF_PTHREAD_COND_T-1] of char; + ___align : clong; + ); + 1 : ( + {$endif} __c_lock: _pthread_fastlock; __c_waiting: pointer; __padding: array[0..48-1-sizeof(_pthread_fastlock)-sizeof(pointer)-sizeof(clonglong)] of byte; __align: clonglong; + {$ifdef USE_PTHREAD_SIZEOF} + ); + {$endif} end; pthread_condattr_t = record + {$ifdef USE_PTHREAD_SIZEOF} + case byte of + 0 : ( + __size : array[0..__SIZEOF_PTHREAD_CONDATTR_T-1] of char; + __align : clong; + ); + 1 : ( + {$endif} __dummy: cint; + {$ifdef USE_PTHREAD_SIZEOF} + ); + {$endif} end; pthread_key_t = cuint; @@ -235,16 +328,38 @@ Type const pthreadrwlocksize = {$ifdef CPU64} 56{$else}32{$endif}; -type +type pthread_rwlock_t = record // should be 56 for 64-bit, 32 bytes for 32-bit mantis #21552 - case boolean of - false : (_data : array[0..pthreadrwlocksize-1] of char); - true : (align : clong); + {$ifdef USE_PTHREAD_SIZEOF} + case byte of + 0 : ( + __size : array[0..__SIZEOF_PTHREAD_RWLOCK_T-1] of char; + __align : clong; + ); + 1 : ( + {$endif} + case boolean of + false : (_data : array[0..pthreadrwlocksize-1] of char); + true : (align : clong); + {$ifdef USE_PTHREAD_SIZEOF} + ); + {$endif} end; pthread_rwlockattr_t = record + {$ifdef USE_PTHREAD_SIZEOF} + case byte of + 0 : ( + __size : array[0..__SIZEOF_PTHREAD_RWLOCKATTR_T-1] of char; + __align : clong; + ); + 1 : ( + {$endif} __lockkind: cint; __pshared: cint; + {$ifdef USE_PTHREAD_SIZEOF} + ); + {$endif} end; sem_t = record @@ -278,7 +393,11 @@ CONST {$ifdef FPC_USE_LIBC} SIG_MAXSIG = 1024; // highest signal version {$else} + {$ifdef cpumips} + SIG_MAXSIG = 1024; // highest signal version + {$else not cupmips} SIG_MAXSIG = 128; // highest signal version + {$endif not cpumips} {$endif} { For getting/setting priority } diff --git a/mips/rtl/linux/signal.inc b/mips/rtl/linux/signal.inc index f4d92a6ce3..dbd4f3d7da 100644 --- a/mips/rtl/linux/signal.inc +++ b/mips/rtl/linux/signal.inc @@ -28,14 +28,20 @@ Const SIG_UNBLOCK = 2; SIG_SETMASK = 4; {$else CPUSPARC} -{$if defined(cpumips) or defined(cpumipsel)} +{$ifdef CPUMIPS} SA_NOCLDSTOP = 1; SA_NOCLDWAIT = $10000; SA_SIGINFO = 8; + SIG_BLOCK = 1; + SIG_UNBLOCK = 2; + SIG_SETMASK = 3; {$else CPUMIPS} SA_NOCLDSTOP = 1; SA_NOCLDWAIT = 2; SA_SIGINFO = 4; + SIG_BLOCK = 0; + SIG_UNBLOCK = 1; + SIG_SETMASK = 2; {$endif CPUMIPS} SA_RESTORER = $04000000; SA_ONSTACK = $08000000; @@ -47,16 +53,13 @@ Const SA_NOMASK = SA_NODEFER; SA_ONESHOT = SA_RESETHAND; - SIG_BLOCK = 0; - SIG_UNBLOCK = 1; - SIG_SETMASK = 2; {$endif CPUSPARC} SIG_DFL = 0 ; SIG_IGN = 1 ; SIG_ERR = -1 ; -{$ifdef cpusparc} +{$ifdef CPUSPARC} SIGHUP = 1; SIGINT = 2; SIGQUIT = 3; @@ -99,15 +102,37 @@ Const SIGTRAP = 5; SIGABRT = 6; SIGIOT = 6; - SIGBUS = 7; SIGFPE = 8; SIGKILL = 9; - SIGUSR1 = 10; SIGSEGV = 11; - SIGUSR2 = 12; SIGPIPE = 13; SIGALRM = 14; - SIGTerm = 15; + SIGTERM = 15; +{$ifdef CPUMIPS} + SIGEMT = 7; + SIGBUS = 10; + SIGSYS = 12; + SIGUSR1 = 16; + SIGUSR2 = 17; + SIGCHLD = 18; + SIGPWR = 19; + SIGWINCH = 20; + SIGURG = 21; + SIGIO = 22; + SIGPOLL = 22; + SIGSTOP = 23; + SIGTSTP = 24; + SIGCONT = 25; + SIGTTIN = 26; + SIGTTOU = 27; + SIGVTALRM = 28; + SIGPROF = 29; + SIGXCPU = 30; + SIGXFSZ = 31; +{$else not CPUMIPS} + SIGBUS = 7; + SIGUSR1 = 10; + SIGUSR2 = 12; SIGSTKFLT = 16; SIGCHLD = 17; SIGCONT = 18; @@ -125,6 +150,7 @@ Const SIGPOLL = SIGIO; SIGPWR = 30; SIGUNUSED = 31; +{$endif not CPUMIPS} {$endif cpusparc} { si_code field values for tsiginfo.si_code when si_signo = SIGFPE } @@ -150,8 +176,13 @@ type psiginfo = ^tsiginfo; tsiginfo = record si_signo : longint; +{$ifdef CPUMIPS} + si_code : longint; + si_errno : longint; +{$else not CPUMIPS} si_errno : longint; si_code : longint; +{$endif not CPUMIPS} _sifields : record case longint of 0 : ( _pad : array[0..(SI_PAD_SIZE)-1] of longint ); @@ -210,10 +241,20 @@ type sa_restorer: sigrestorerhandler_t; end; {$else} + {$ifdef cpumips} + sigactionrec = record + sa_flags: cuint; + sa_handler: sigactionhandler_t; + sa_mask: sigset_t; + sa_restorer: sigrestorerhandler_t; { Doesn't seem to exist on MIPS } + sa_resv : array [0..0] of cint; + end; + {$else not mips} sigactionrec = record sa_handler: sigactionhandler_t; sa_flags: culong; sa_restorer: sigrestorerhandler_t; sa_mask: sigset_t; end; + {$endif not mips} {$endif} diff --git a/mips/rtl/linux/sparc/sighnd.inc b/mips/rtl/linux/sparc/sighnd.inc index cfbfc35149..5182920cfe 100644 --- a/mips/rtl/linux/sparc/sighnd.inc +++ b/mips/rtl/linux/sparc/sighnd.inc @@ -30,7 +30,7 @@ begin FPE_INTDIV: res:=200; FPE_INTOVF: - res:=205; + res:=215; FPE_FLTDIV: res:=200; FPE_FLTOVF: diff --git a/mips/rtl/linux/unxsockh.inc b/mips/rtl/linux/unxsockh.inc index d85ad09b4c..ccbad9a18d 100644 --- a/mips/rtl/linux/unxsockh.inc +++ b/mips/rtl/linux/unxsockh.inc @@ -170,10 +170,10 @@ Const IPPROTO_RAW = 255; { Raw IP packets. } IPPROTO_MAX = 255; //from /usr/include/bits/in.h -{{ Options for use with etsockopt' and etsockopt' at the IP level. +{ Options for use with getsockopt' and setsockopt' at the IP level. The first word in the comment at the right is the data type used; - "bool" means a boolean value stored in an nt'. } -} + "bool" means a boolean value stored in an int'. } + IP_OPTIONS = 4; { ip_opts; IP per-packet options. } IP_HDRINCL = 3; { int; Header is included with data. } IP_TOS = 1; { int; IP type of service and precedence. } @@ -227,9 +227,9 @@ Const IP_MAX_MEMBERSHIPS = 20; -{ Options for use with etsockopt' and etsockopt' at the IPv6 level. +{ Options for use with getsockopt' and setsockopt' at the IPv6 level. The first word in the comment at the right is the data type used; - "bool" means a boolean value stored in an nt'. } + "bool" means a boolean value stored in an int'. } IPV6_ADDRFORM = 1; IPV6_PKTINFO = 2; IPV6_HOPOPTS = 3; diff --git a/mips/rtl/linux/x86_64/dllprt0.as b/mips/rtl/linux/x86_64/dllprt0.as index 477da7785b..c86bbfd0c6 100644 --- a/mips/rtl/linux/x86_64/dllprt0.as +++ b/mips/rtl/linux/x86_64/dllprt0.as @@ -41,8 +41,8 @@ FPC_SHARED_LIB_START: jmp _startlib@PLT .text - .globl _start - .type _start,@function + .globl _startlib + .type _startlib,@function _startlib: pushq %rbx movq operatingsystem_parameter_argc@GOTPCREL(%rip),%rbx diff --git a/mips/rtl/m68k/m68k.inc b/mips/rtl/m68k/m68k.inc index 56636eacc0..d007587ab5 100644 --- a/mips/rtl/m68k/m68k.inc +++ b/mips/rtl/m68k/m68k.inc @@ -41,7 +41,7 @@ function get_frame : pointer; assembler; {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR} -function get_caller_addr(framebp : pointer) : pointer; +function get_caller_addr(framebp : pointer;addr:pointer=nil) : pointer; begin asm move.l framebp,a0 @@ -55,7 +55,7 @@ function get_caller_addr(framebp : pointer) : pointer; {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME} -function get_caller_frame(framebp : pointer) : pointer; +function get_caller_frame(framebp : pointer;addr:pointer=nil) : pointer; begin asm move.l FRAMEBP,a0 diff --git a/mips/rtl/mips/mathu.inc b/mips/rtl/mips/mathu.inc index 9f3ffff15a..8b3063dfa6 100644 --- a/mips/rtl/mips/mathu.inc +++ b/mips/rtl/mips/mathu.inc @@ -13,8 +13,29 @@ **********************************************************************} { exported by the system unit } -//!!!function get_fsr : dword;external name 'FPC_GETFSR'; -//!!!procedure set_fsr(fsr : dword);external name 'FPC_SETFSR'; +function get_fsr : dword;external name 'FPC_GETFSR'; +procedure set_fsr(fsr : dword);external name 'FPC_SETFSR'; + +const + { FPU enable exception bits for FCSR register } + fpu_enable_inexact = $80; + fpu_enable_underflow = $100; + fpu_enable_overflow = $200; + fpu_enable_div_zero = $400; + fpu_enable_invalid = $800; + fpu_enable_mask = $F80; + default_fpu_enable = fpu_enable_div_zero or fpu_enable_invalid; + + fpu_flags_mask = $7C; + fpu_cause_mask = $3F000; + + { FPU rounding mask and values } + fpu_rounding_mask = $3; + fpu_rounding_nearest = 0; + fpu_rounding_towards_zero = 1; + fpu_rounding_plus_inf = 2; + fpu_rounding_minus_inf = 3; + function FPUExceptionMaskToSoftFloatMask(const Mask: TFPUExceptionMask): byte; begin @@ -35,22 +56,37 @@ end; function GetRoundMode: TFPURoundingMode; begin -//!!! result:=TFPURoundingMode(get_fsr shr 30); + result:=TFPURoundingMode(get_fsr and 3); end; function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode; + var + fpu_round : longint; begin + case (RoundMode) of rmNearest : - softfloat_rounding_mode := float_round_nearest_even; + begin + softfloat_rounding_mode := float_round_nearest_even; + fpu_round:=fpu_rounding_nearest; + end; rmTruncate : - softfloat_rounding_mode := float_round_to_zero; - rmUp : - softfloat_rounding_mode := float_round_up; - rmDown : - softfloat_rounding_mode := float_round_down; - end; -//!!! set_fsr((get_fsr and $3fffffff) or (dword(RoundMode) shl 30)); + begin + softfloat_rounding_mode := float_round_to_zero; + fpu_round:=fpu_rounding_towards_zero; + end; + rmUp : + begin + softfloat_rounding_mode := float_round_up; + fpu_round:=fpu_rounding_plus_inf; + end; + rmDown : + begin + softfloat_rounding_mode := float_round_down; + fpu_round:=fpu_rounding_minus_inf; + end; + end; + set_fsr((get_fsr and not fpu_rounding_mask) or fpu_round); //!!! result:=TFPURoundingMode(get_fsr shr 30); end; @@ -71,26 +107,26 @@ function GetExceptionMask: TFPUExceptionMask; var fsr : dword; begin -//!!! fsr:=get_fsr; + fsr:=get_fsr; result:=[]; - { invalid operation: bit 27 } - if (fsr and (1 shl 27))=0 then + { invalid operation } + if (fsr and fpu_enable_invalid)=0 then include(result,exInvalidOp); - { zero divide: bit 24 } - if (fsr and (1 shl 24))=0 then - include(result,exInvalidOp); + { zero divide } + if (fsr and fpu_enable_div_zero)=0 then + include(result,exZeroDivide); - { overflow: bit 26 } - if (fsr and (1 shl 26))=0 then - include(result,exInvalidOp); + { overflow } + if (fsr and fpu_enable_overflow)=0 then + include(result,exOverflow); - { underflow: bit 25 } - if (fsr and (1 shl 25))=0 then + { underflow: } + if (fsr and fpu_enable_underflow)=0 then include(result,exUnderflow); - { Precision (inexact result): bit 23 } - if (fsr and (1 shl 23))=0 then + { Precision (inexact result) } + if (fsr and fpu_enable_inexact)=0 then include(result,exPrecision); end; @@ -100,40 +136,43 @@ function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask; var fsr : dword; begin -//!!! fsr:=get_fsr; + fsr:=get_fsr; - { invalid operation: bit 27 } + { invalid operation } if (exInvalidOp in mask) then - fsr:=fsr and not(1 shl 27) + fsr:=fsr and not(fpu_enable_invalid) else - fsr:=fsr or (1 shl 27); + fsr:=fsr or (fpu_enable_invalid); - { zero divide: bit 24 } + { zero divide } if (exZeroDivide in mask) then - fsr:=fsr and not(1 shl 24) + fsr:=fsr and not(fpu_enable_div_zero) else - fsr:=fsr or (1 shl 24); + fsr:=fsr or (fpu_enable_div_zero); - { overflow: bit 26 } + { overflow } if (exOverflow in mask) then - fsr:=fsr and not(1 shl 26) + fsr:=fsr and not(fpu_enable_overflow) else - fsr:=fsr or (1 shl 26); + fsr:=fsr or (fpu_enable_overflow); - { underflow: bit 25 } + { underflow } if (exUnderflow in mask) then - fsr:=fsr and not(1 shl 25) + fsr:=fsr and not(fpu_enable_underflow) else - fsr:=fsr or (1 shl 25); + fsr:=fsr or (fpu_enable_underflow); - { Precision (inexact result): bit 23 } + { Precision (inexact result) } if (exPrecision in mask) then - fsr:=fsr and not(1 shl 23) + fsr:=fsr and not(fpu_enable_inexact) else - fsr:=fsr or (1 shl 23); + fsr:=fsr or (fpu_enable_inexact); + + { Reset flags and cause } + fsr := fsr and not (fpu_flags_mask or fpu_cause_mask); { update control register contents } -//!!! set_fsr(fsr); + set_fsr(fsr); softfloat_exception_mask:=FPUExceptionMaskToSoftFloatMask(mask); end; @@ -141,6 +180,6 @@ function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask; procedure ClearExceptions(RaisePending: Boolean =true); begin -//!!! set_fsr(get_fsr and $fffffc1f); + set_fsr(get_fsr and not (fpu_flags_mask or fpu_cause_mask)); end; diff --git a/mips/rtl/mips/mips.inc b/mips/rtl/mips/mips.inc index 22c0ba4dc6..f0d839c164 100644 --- a/mips/rtl/mips/mips.inc +++ b/mips/rtl/mips/mips.inc @@ -37,6 +37,26 @@ function get_got_z : pointer;assembler;nostackframe;[public, alias: 'FPC_GETGOT_ move $2,$28 end; +const + { FPU enable exception bits for FCSR register } + fpu_enable_inexact = $80; + fpu_enable_underflow = $100; + fpu_enable_overflow = $200; + fpu_enable_div_zero = $400; + fpu_enable_invalid = $800; + fpu_enable_mask = $F80; + default_fpu_enable = fpu_enable_div_zero or fpu_enable_invalid; + + fpu_flags_mask = $7C; + fpu_cause_mask = $3F000; + + { FPU rounding mask and values } + fpu_rounding_mask = $3; + fpu_rounding_nearest = 0; + fpu_rounding_towards_zero = 1; + fpu_rounding_plus_inf = 2; + fpu_rounding_minus_inf = 3; + procedure fpc_cpuinit; var @@ -45,11 +65,17 @@ var { don't let libraries influence the FPU cw set by the host program } if not IsLibrary then begin - { enable div by 0 and invalid operation fpu exceptions } + tmp32 := get_fsr(); + { enable div by 0 and invalid operation fpu exceptions, + disable the other exceptions } + tmp32 := (tmp32 and not fpu_enable_mask) or default_fpu_enable; + { Reset flags and cause } + tmp32 := tmp32 and not (fpu_flags_mask or fpu_cause_mask); + { round towards nearest; ieee compliant arithmetics } + tmp32 := (tmp32 and not fpu_rounding_mask) or fpu_rounding_nearest; - tmp32 := get_fsr(); - set_fsr(tmp32 and $fffffffc); + set_fsr(tmp32); end; end; @@ -70,25 +96,105 @@ function get_frame:pointer;assembler;nostackframe; Further, we need to know the pc } // lw $2,0($sp) - lui $2,0 + move $2,$30 end; -{$define FPC_SYSTEM_HAS_GET_CALLER_ADDR} -function get_caller_addr(framebp:pointer):pointer;assembler;nostackframe; - asm - // lw $2,4($4) // #movl 4(%eax),%eax - lui $2,0 +{ Try to find previous $fp,$ra register pair + reset both to nil if failure } +{$define FPC_SYSTEM_HAS_GET_CALLER_STACKINFO} +procedure get_caller_stackinfo(var framebp,addr : pointer); +const + instr_size = 4; + MAX_INSTRUCTIONS = 64000; +type + instr_p = pdword; + reg_p = ppointer; +var + instr,stackpos : dword; + i,LocalSize : longint; + ra_offset, s8_offset : longint; + current_ra : pointer; +begin + { Here we need to use GDB approach, + starting at addr + go back to lower $ra values until we find a + position with ADDIU $sp,$sp,-LocalSize + } + if addr=nil then + begin + framebp:=nil; + exit; + end; + Try + current_ra:=addr; + ra_offset:=-1; + s8_offset:=-1; + i:=0; + LocalSize:=0; + repeat + inc(i); + dec(current_ra,4); + instr:=instr_p(current_ra)^; + if (instr shr 16 = $27bd) then + begin + { we found the instruction, + local size is the lo part } + LocalSize:=smallint(instr and $ffff); + break; + end; + until i> MAX_INSTRUCTIONS; + if LocalSize <> 0 then + begin + repeat + inc(current_ra,4); + instr:=instr_p(current_ra)^; + if (instr shr 16 = $afbf) then + ra_offset:=smallint(instr and $ffff) + else if (instr shr 16 = $afbe) then + s8_offset:=smallint(instr and $ffff); + until (current_ra >= addr) + or ((ra_offset<>-1) and (s8_offset<>-1)); + if ra_offset<>-1 then + begin + stackpos:=dword(framebp+LocalSize+ra_offset); + addr:=reg_p(stackpos)^; + end + else + addr:=nil; + if s8_offset<>-1 then + begin + stackpos:=dword(framebp+LocalSize+s8_offset); + framebp:=reg_p(stackpos)^; + end + else + framebp:=nil; + end; + Except + framebp:=nil; + addr:=nil; end; +end; +{$define FPC_SYSTEM_HAS_GET_PC_ADDR} +function get_pc_addr : pointer;assembler;nostackframe; +asm + move $2,$31 +end; -{$define FPC_SYSTEM_HAS_GET_CALLER_FRAME} -function get_caller_frame(framebp:pointer):pointer;assembler;nostackframe; - asm - // lw $2,0($4) // #movl (%eax),%eax - lui $2,0 - end; +{$define FPC_SYSTEM_HAS_GET_CALLER_ADDR} +function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer; +begin + get_caller_stackinfo(framebp,addr); + get_caller_addr:=addr; +end; +{$define FPC_SYSTEM_HAS_GET_CALLER_FRAME} +function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer; +begin + get_caller_stackinfo(framebp,addr); + get_caller_frame:=framebp; +end; {$define FPC_SYSTEM_HAS_SPTR} function Sptr:Pointer;assembler;nostackframe; diff --git a/mips/rtl/objpas/fgl.pp b/mips/rtl/objpas/fgl.pp index 1418c1cbb7..0b6670334f 100644 --- a/mips/rtl/objpas/fgl.pp +++ b/mips/rtl/objpas/fgl.pp @@ -1164,7 +1164,7 @@ end; function TFPSMap.BinaryCompareData(Data1, Data2: Pointer): Integer; begin - Result := CompareByte(Data1^, Data1^, FDataSize); + Result := CompareByte(Data1^, Data2^, FDataSize); end; procedure TFPSMap.SetOnKeyPtrCompare(Proc: TFPSListCompareFunc); diff --git a/mips/rtl/objpas/strutils.pp b/mips/rtl/objpas/strutils.pp index 8290314cb6..aef57f043e 100644 --- a/mips/rtl/objpas/strutils.pp +++ b/mips/rtl/objpas/strutils.pp @@ -97,6 +97,13 @@ Function PosEx(c:char; const S: string; Offset: Cardinal): Integer; function StringsReplace(const S: string; OldPattern, NewPattern: array of string; Flags: TReplaceFlags): string; { --------------------------------------------------------------------- + Delphi compat + ---------------------------------------------------------------------} + +Function ReplaceStr(const AText, AFromText, AToText: string): string;inline; +Function ReplaceText(const AText, AFromText, AToText: string): string;inline; + +{ --------------------------------------------------------------------- Soundex Functions. ---------------------------------------------------------------------} @@ -745,6 +752,20 @@ begin end; { --------------------------------------------------------------------- + Delphi compat + ---------------------------------------------------------------------} + +Function ReplaceStr(const AText, AFromText, AToText: string): string;inline; +begin + AnsiReplaceStr(AText, AFromText, AToText); +end; + +Function ReplaceText(const AText, AFromText, AToText: string): string;inline; +begin + AnsiReplaceText(AText, AFromText, AToText); +end; + +{ --------------------------------------------------------------------- Soundex Functions. ---------------------------------------------------------------------} Const diff --git a/mips/rtl/openbsd/errno.inc b/mips/rtl/openbsd/errno.inc index b5013276da..2f41d87ce2 100644 --- a/mips/rtl/openbsd/errno.inc +++ b/mips/rtl/openbsd/errno.inc @@ -78,7 +78,6 @@ Const ESysEPROTONOSUPPORT = 43; { Protocol not supported } ESysESOCKTNOSUPPORT = 44; { Socket type not supported } ESysEOPNOTSUPP = 45; { Operation not supported } - ESysENOTSUP = ESysEOPNOTSUPP; { Operation not supported } ESysEPFNOSUPPORT = 46; { Protocol family not supported } ESysEAFNOSUPPORT = 47; { Address family not supported by protocol family } ESysEADDRINUSE = 48; { Address already in use } @@ -126,12 +125,15 @@ Const ESysEFTYPE = 79; { Inappropriate file type or format } ESysEAUTH = 80; { Authentication error } ESysENEEDAUTH = 81; { Need authenticator } - ESysEIDRM = 82; { Identifier removed } - ESysENOMSG = 83; { No message of desired type } - ESysEOVERFLOW = 84; { Value too large to be stored in data type } - ESysECANCELED = 85; { Operation canceled } - ESysEILSEQ = 86; { Illegal byte sequence } - ESysELAST = 86; { Must be equal largest errno } - - + ESysEIPSEC = 82; { IPsec processing failure } + ESysENOATTR = 83; { Attribute not found } + ESysEILSEQ = 84; { Illegal byte sequence } + ESysENOMEDIUM = 85; { No medium found } + ESysEMEDIUMTYPE = 86; { Wrong Medium Type } + ESysEOVERFLOW = 87; { Value too large to be stored in data type } + ESysECANCELED = 88; { Operation canceled } + ESysEIDRM = 89; { Identifier removed } + ESysENOMSG = 90; { No message of desired type } + ESysENOTSUP = 91; { Not supported } + ESysELAST = ESysENOTSUP; { Must be equal largest errno } diff --git a/mips/rtl/powerpc/powerpc.inc b/mips/rtl/powerpc/powerpc.inc index 7a8645e007..278d53df68 100644 --- a/mips/rtl/powerpc/powerpc.inc +++ b/mips/rtl/powerpc/powerpc.inc @@ -1024,7 +1024,7 @@ indicated by the first bit set to 1. This is checked below.} {Both routines below assumes that framebp is a valid framepointer or nil.} {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR} -function get_caller_addr(framebp:pointer):pointer;assembler;{$ifdef SYSTEMINLINE}inline;{$endif} nostackframe; +function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;assembler;{$ifdef SYSTEMINLINE}inline;{$endif} nostackframe; asm cmplwi r3,0 beq .Lcaller_addr_invalid @@ -1048,7 +1048,7 @@ end; {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME} -function get_caller_frame(framebp:pointer):pointer;assembler;{$ifdef SYSTEMINLINE}inline;{$endif} nostackframe; +function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;assembler;{$ifdef SYSTEMINLINE}inline;{$endif} nostackframe; asm cmplwi r3,0 beq .Lcaller_frame_invalid diff --git a/mips/rtl/powerpc64/powerpc64.inc b/mips/rtl/powerpc64/powerpc64.inc index f613bb7ddb..53dc54f7b1 100644 --- a/mips/rtl/powerpc64/powerpc64.inc +++ b/mips/rtl/powerpc64/powerpc64.inc @@ -520,7 +520,7 @@ asm end; {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR} -function get_caller_addr(framebp:pointer):pointer;assembler;{$ifdef SYSTEMINLINE}inline;{$endif} nostackframe; +function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;assembler;{$ifdef SYSTEMINLINE}inline;{$endif} nostackframe; asm cmpldi r3,0 beq .Lcaller_addr_frame_null @@ -534,7 +534,7 @@ end; {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME} -function get_caller_frame(framebp:pointer):pointer;assembler;{$ifdef SYSTEMINLINE}inline;{$endif} nostackframe; +function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;assembler;{$ifdef SYSTEMINLINE}inline;{$endif} nostackframe; asm cmpldi r3,0 beq .Lcaller_frame_null diff --git a/mips/rtl/sparc/sparc.inc b/mips/rtl/sparc/sparc.inc index a4b30eb84d..d773161802 100644 --- a/mips/rtl/sparc/sparc.inc +++ b/mips/rtl/sparc/sparc.inc @@ -53,7 +53,7 @@ Procedure SysInitFPU;{$ifdef SYSTEMINLINE}inline;{$endif} round towards zero; ieee compliant arithmetics } set_fsr((get_fsr and $3fbfffff) or $09000000); end; - + {$define FPC_SYSTEM_HAS_SYSRESETFPU} Procedure SysResetFPU;{$ifdef SYSTEMINLINE}inline;{$endif} begin @@ -77,7 +77,7 @@ function get_frame:pointer;assembler;nostackframe; {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR} -function get_caller_addr(framebp:pointer):pointer;assembler;nostackframe; +function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;assembler;nostackframe; asm { framebp = %o0 } subcc %o0,0,%o0 @@ -93,7 +93,7 @@ function get_caller_addr(framebp:pointer):pointer;assembler;nostackframe; {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME} -function get_caller_frame(framebp:pointer):pointer;assembler;nostackframe; +function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;assembler;nostackframe; asm { framebp = %o0 } subcc %o0,0,%o0 diff --git a/mips/rtl/unix/ipc.pp b/mips/rtl/unix/ipc.pp index b506ea9012..66e9e3c13e 100644 --- a/mips/rtl/unix/ipc.pp +++ b/mips/rtl/unix/ipc.pp @@ -548,12 +548,12 @@ const MAX_SOPS = 5; {$if not defined(aix) and not defined(darwin)} - SEM_GETNCNT = 3; { Return the value of sempid {READ} } - SEM_GETPID = 4; { Return the value of semval {READ} } - SEM_GETVAL = 5; { Return semvals into arg.array {READ} } - SEM_GETALL = 6; { Return the value of semzcnt {READ} } - SEM_GETZCNT = 7; { Set the value of semval to arg.val {ALTER} } - SEM_SETVAL = 8; { Set semvals from arg.array {ALTER} } + SEM_GETNCNT = 3; { Return the value of sempid (READ) } + SEM_GETPID = 4; { Return the value of semval (READ) } + SEM_GETVAL = 5; { Return semvals into arg.array (READ) } + SEM_GETALL = 6; { Return the value of semzcnt (READ) } + SEM_GETZCNT = 7; { Set the value of semval to arg.val (ALTER) } + SEM_SETVAL = 8; { Set semvals from arg.array (ALTER) } SEM_SETALL = 9; {$endif} diff --git a/mips/rtl/unix/scripts/check_consts.sh b/mips/rtl/unix/scripts/check_consts.sh index 8f6655bdc9..a7e08b1556 100755 --- a/mips/rtl/unix/scripts/check_consts.sh +++ b/mips/rtl/unix/scripts/check_consts.sh @@ -20,6 +20,8 @@ os=`uname -s` if [ "$os" == "NetBSD" ] ; then needgsed=1 +else + needgsed=0 fi SED=sed @@ -37,7 +39,7 @@ fi for file in $@ ; do echo "Looking for constants in \"$file\"" -$SED -n "s:.*[[:space:]]\([a-zA-Z_][a-zA-Z_0-9]*\)[[:space:]]*=[[:space:]]*\([-+]*[0-9][xX]*[0-9+-\*/]*\)[[:space:]]*;.*:test_const \1 \2:p" $file > check_const_list.sh +$SED -n -e "s:.*[[:space:]]\([a-zA-Z_][a-zA-Z_0-9]*\)[[:space:]]*=[[:space:]]*\([-+]*[0-9][xX]*[-0-9+[:space:]]*\)[[:space:]]*;.*:test_const \1 \2:p" $file > check_const_list.sh test_const () { diff --git a/mips/rtl/unix/scripts/check_errno.sh b/mips/rtl/unix/scripts/check_errno.sh index 22f10d4d6a..c07e28a0f2 100755 --- a/mips/rtl/unix/scripts/check_errno.sh +++ b/mips/rtl/unix/scripts/check_errno.sh @@ -21,10 +21,24 @@ else verbose=0 fi +if [ "$1" == "addall" ] ; then + addall=1 + echo "Adding all entries to errno-new.inc" + shift +else + addall=0 +fi + # Location of error number in system header -errno_header="/usr/include/asm-generic/errno-base.h /usr/include/asm-generic/errno.h" -errno_include=./errno.inc +errno_headers="/usr/include/asm-generic/errno-base.h /usr/include/asm-generic/errno.h" + +if [ "$1" != "" ] ; then + errno_include=$1 + echo "Using $errno_include file" +else + errno_include=./errno.inc +fi # Sustitution made to pass from fpc syscall number # to system define @@ -53,18 +67,53 @@ fi # Use gcc with --save-temps option to create .i file $CC --save-temps -c ./test-errno.c # list of errno.h headers listed -errno_headers=` sed -n "s:.*\"\(.*\.h\)\".*:\1:p" test-errno.i |sort | uniq` -echo "Headers found are \"$errno_headers\"" +errno_headers_CC=` sed -n "s:.*\"\(.*\.h\)\".*:\1:p" test-errno.i |sort | uniq` +echo "Headers found are \"$errno_headers_CC\"" -if [ "$errno_headers" != "" ] ; then - errno_header="$errno_headers" +if [ "$errno_headers_CC" != "" ] ; then + errno_headers="$errno_headers_CC" fi # You should only need to change the variables above sed -n "s:^[[:space:]]*${fpc_errno_prefix}\\([_a-zA-Z0-9]*\\)[[:space:]]*=[[:space:]]*\\([0-9][0-9]*\\).*:check_errno_number ${errno_prefix}\1 \2:p" ${errno_include} > check_errno_list.sh -sed -n "s:#define[[:space:]]*${errno_prefix}\\([_a-zA-Z0-9]*\\)[[:space:]][[:space:]]*\\(-*[0-9A-Za-z_]*\\).*:check_reverse_errno_number ${fpc_errno_prefix}\1 \2:p" ${errno_header} > check_reverse_errno_list.sh +sed -n "s:#define[[:space:]]*${errno_prefix}\\([_a-zA-Z0-9]*\\)[[:space:]][[:space:]]*\\(-*[0-9A-Za-z_]*\\)[[:space:]]*\(.*\):check_reverse_errno_number ${fpc_errno_prefix}\1 \2 \"\3\":p" ${errno_headers} > check_reverse_errno_list.sh + +function rpad { + word="$1" + while [ ${#word} -lt $2 ]; do + word="$word$3"; + done; + echo "$word"; +} + +function compile_errno () +{ + errname=$1 + errvalue=$2 +# Test C file to grab all loaded headers +cat > test-errno.c <<EOF +#include <errno.h> +#include <stdio.h> + +int +main () +{ + printf ("$errname=%d\n",$errname); + return 0; +} +EOF +$CC -o ./test-errno ./test-errno.c +compiledvalue=`./test-errno` +if [ "$compiledvalue" == "$errname=$errvalue" ] ; then + if [ $verbose -ne 0 ]; then + echo "GCC reports $compiledvalue OK" + fi +else + echo "GCC reports $compiledvalue, but $errvalue is expected" +fi +} function check_errno_number () { @@ -75,10 +124,11 @@ function check_errno_number () fi # Remember value of this constant eval ${sys}=${value} + compile_errno $sys $value - found=`sed -n "/#define[[:space:]][[:space:]]*${sys}[^A-Za-z0-9_]/p" ${errno_header}` - val=`sed -n "s:#define[[:space:]][[:space:]]*${sys}[^A-Za-z0-9_][^A-Za-z0-9_]*\([0-9]*\).*:\1:p" ${errno_header}` - extval=`sed -n "s:#define[[:space:]][[:space:]]*${sys}[^A-Za-z0-9_][^A-Za-z0-9_]*\([0-9A-Za-z_]*\).*:\1:p" ${errno_header}` + found=`sed -n "/#define[[:space:]][[:space:]]*${sys}[^A-Za-z0-9_]/p" ${errno_headers}` + val=`sed -n "s:#define[[:space:]][[:space:]]*${sys}[^A-Za-z0-9_][^A-Za-z0-9_]*\([0-9]*\).*:\1:p" ${errno_headers}` + extval=`sed -n "s:#define[[:space:]][[:space:]]*${sys}[^A-Za-z0-9_][^A-Za-z0-9_]*\([0-9A-Za-z_]*\).*:\1:p" ${errno_headers}` if [ $verbose -ne 0 ] ; then echo Test for $sys found \"${found}\" \"${value}\" \"${val}\" fi @@ -87,13 +137,16 @@ function check_errno_number () echo ${sys} value ${val} is correct fi else + if [ $verbose -ne 0 ] ; then + echo "${sys} val=\"$val\", extval=\"$extval\"" + fi if [ "${val}" == "" ] ; then - foundvalue=`sed -n "/#define.*[^A-Za-z0-9_]${value}$/p" ${errno_header}` + foundvalue=`sed -n "/#define.*[^A-Za-z0-9_]${value}$/p" ${errno_headers}` if [ "${foundvalue}" == "" ] ; then - foundvalue=`sed -n "s:\/\* ${value} is compa: ${value} is compa:p" ${errno_header}` + foundvalue=`sed -n "s:\/\* ${value} is compa: ${value} is compa:p" ${errno_headers}` fi fi - if [ "$extval" != "" ] ; then + if [ "$extval" != "$val" ] ; then eval indirectval=\$$extval echo "indirectval =\"$indirectval\" for \"$extval\"" if [ "$indirectval" != "$value" ] ; then @@ -107,19 +160,46 @@ function check_errno_number () fi } +function write_errno_new_head () +{ + echo "{ File generated by $0" > $errnonew + uname_info=`uname -s -r -m` + echo " generated on \"$uname_info\" machine" >> $errnonew + echo "List of missing system error number found in" >> $errnonew + echo "$errno_headers" >> $errnonew + echo "}" >> $errnonew +} function check_reverse_errno_number () { errname=$1 errvalue=$2 + rpaderrname=$(rpad $errname 20 " ") + if ! [[ "$errvalue" =~ ^[0-9]+$ ]] ; then + eval errvalue=\$$errvalue + fi + + printf -v padd "%s = %4d" "$rpaderrname" $errvalue + found=`grep -i -w $1 ${errno_include}` + comment="$3" + comment=${comment##\/\*} + comment=${comment%%\*\/} if [ "${found}" == "" ] ; then echo "Error ${errname}, value ${errvalue}, not in ${errno_include} file" if [ $addtoerrno -eq 0 ] ; then addtoerrno=1 - echo "{ List of missing system error number found in $errno_header }" > $errnonew + write_errno_new_head + fi + echo " $padd; { $comment }" >> $errnonew + else + if [ $addall -eq 1 ] ; then + if [ $addtoerrno -eq 0 ] ; then + addtoerrno=1 + write_errno_new_head + fi + echo " $padd; { $comment }" >> $errnonew fi - echo " $errname = $errvalue;" >> $errnonew fi } diff --git a/mips/rtl/win/crt.pp b/mips/rtl/win/crt.pp index 6369f4c247..824b31e44f 100644 --- a/mips/rtl/win/crt.pp +++ b/mips/rtl/win/crt.pp @@ -711,7 +711,14 @@ begin WriteChar(f.buffer[i]); end else - s:=s+f.buffer[i]; + begin + if length(s)=255 then + begin + WriteStr(s); + s:=''; + end; + s:=s+f.buffer[i]; + end; if s<>'' then WriteStr(s); SetScreenCursor(CurrX, CurrY); diff --git a/mips/rtl/x86_64/x86_64.inc b/mips/rtl/x86_64/x86_64.inc index 6a5947ef07..70e11076e4 100644 --- a/mips/rtl/x86_64/x86_64.inc +++ b/mips/rtl/x86_64/x86_64.inc @@ -35,9 +35,14 @@ asm end; {$ENDIF not INTERNAL_BACKTRACE} +{$define FPC_SYSTEM_HAS_GET_PC_ADDR} +function get_pc_addr:pointer;assembler;nostackframe; +asm + movq (%rsp),%rax +end; {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR} -function get_caller_addr(framebp:pointer):pointer;{$ifdef SYSTEMINLINE}inline;{$endif} +function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;{$ifdef SYSTEMINLINE}inline;{$endif} begin get_caller_addr:=framebp; if assigned(framebp) then @@ -46,7 +51,7 @@ end; {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME} -function get_caller_frame(framebp:pointer):pointer;{$ifdef SYSTEMINLINE}inline;{$endif} +function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;{$ifdef SYSTEMINLINE}inline;{$endif} begin get_caller_frame:=framebp; if assigned(framebp) then @@ -942,7 +947,7 @@ Procedure SysInitFPU; { these locals are so we don't have to hack pic code in the assembler } localmxcsr: dword; localfpucw: word; - + begin localmxcsr:=mxcsr; localfpucw:=fpucw; |