2 * Copyright © 2009 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its
15 * contributors may be used to endorse or promote products derived from this
16 * software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * @APPLE_LICENSE_HEADER_END@
33 #include <mach-o/loader.h>
34 #include <mach-o/nlist.h>
35 #include <mach-o/reloc.h>
36 #include <mach-o/sparc/reloc.h>
37 #include "stuff/bytesex.h"
38 #include "stuff/symbol.h"
40 #include "dyld_bind_info.h"
41 #include "ofile_print.h"
42 #include "../as/sparc-opcode.h"
47 /* Sign-extend a value which is N bits long. */
48 #define SEX(value, bits) \
49 ((((int)(value)) << ((8 * sizeof (int)) - bits)) \
50 >> ((8 * sizeof (int)) - bits) )
52 static char *reg_names
[] =
53 { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
54 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
55 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
56 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
57 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
58 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
59 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
60 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
61 "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr"
64 #define freg_names (®_names[4 * 8])
80 #ifdef __LITTLE_ENDIAN__
98 unsigned int IMM13
:13;
100 #ifdef __LITTLE_ENDIAN__
101 unsigned int IMM13
:13;
103 unsigned int anrs1
:5;
111 #ifdef __BIG_ENDIAN__
116 unsigned int DISP22
:22;
118 #ifdef __LITTLE_ENDIAN__
119 unsigned int DISP22
:22;
128 #ifdef __BIG_ENDIAN__
130 unsigned int adisp30
:30;
132 #ifdef __LITTLE_ENDIAN__
133 unsigned int adisp30
:30;
141 #define rs1 ldst.anrs1
142 #define asi ldst.anasi
143 #define rs2 ldst.anrs2
145 #define imm13 IMM13.IMM13
146 #define disp22 branch.DISP22
148 #define disp30 call.adisp30
150 #define SYM_PRINT(a,b,c) print_symbolic((a),(b),(c),relocs, nrelocs, symbols, \
151 nsymbols, sorted_symbols, \
152 nsorted_symbols, strings, \
153 strings_size, verbose)
155 static int opcodes_sorted
= 0;
157 static int compare_opcodes ();
160 /* Nonzero if INSN is the opcode for a delayed branch. */
162 is_delayed_branch (insn
)
163 union sparc_insn insn
;
167 for (i
= 0; i
< NUMOPCODES
; ++i
) {
168 struct sparc_opcode
*opcode
= &sparc_opcodes
[i
];
170 if ((opcode
->match
& insn
.code
) == opcode
->match
171 && (opcode
->lose
& insn
.code
) == 0)
172 return (opcode
->flags
& F_DELAYED
);
177 /* find_lo_value attempts to look ahead in the code and find the %lo
178 value corresponding to the current %hi and return its value.
179 The %lo may have been optimized away by the assembler and we don't
180 know how many intermediate instructions there will be between the hi/lo
181 combination. To limit the search, we only look a maximum of 5 insn
184 #define MAX_LO_LOOKAHEAD 5
190 union sparc_insn insn
)
192 int index
, next_insn
;
195 while (++index
< MAX_LO_LOOKAHEAD
) {
196 memcpy(&next_insn
, section
+ 4*index
, sizeof (unsigned int));
199 #endif /* NOT_USED */
202 print_address_func(unsigned int addr
)
204 printf("0x%x", addr
);
207 /* print a label symbol. Modified from print_label in ofile_print.c
208 * Prints the label it found and returns TRUE or prints nothing
215 enum bool colon_and_newline
,
216 struct symbol
*sorted_symbols
,
217 uint32_t nsorted_symbols
)
219 int32_t high
, low
, mid
;
222 high
= nsorted_symbols
- 1;
223 mid
= (high
- low
) / 2;
225 if(sorted_symbols
[mid
].n_value
== addr
){
226 printf("%s", sorted_symbols
[mid
].name
);
227 if(colon_and_newline
== TRUE
)
231 if(sorted_symbols
[mid
].n_value
> addr
){
233 mid
= (high
+ low
) / 2;
237 mid
= (high
+ low
) / 2;
243 /* print symbol name for an address and reloc entry.
244 print either symbol found or print the value of the address but print
252 struct relocation_info
*relocs
,
254 struct nlist
*symbols
,
256 struct symbol
*sorted_symbols
,
257 uint32_t nsorted_symbols
,
259 uint32_t strings_size
,
262 struct relocation_info
*rp
, *rp_pair
;
263 uint32_t i
, r_address
, r_symbolnum
, r_type
, r_extern
,
264 r_value
, r_scattered
, pair_r_type
, pair_r_value
;
265 int32_t reloc_found
, offset
;
267 const char *name
, *add
, *sub
;
268 struct scattered_relocation_info
*srp
;
279 /* if verbose output is not requested, don't even attempt lookup */
282 printf("0x%x", (unsigned int) value
);
286 /* Check all reloc entries */
288 for (i
=0, rp
= relocs
; i
<nrelocs
; i
++, rp
++) {
289 if (rp
->r_address
& R_SCATTERED
) {
290 srp
= (struct scattered_relocation_info
*) rp
;
292 r_address
= srp
->r_address
;
294 r_type
= srp
->r_type
;
295 r_value
= srp
->r_value
;
298 r_address
= rp
->r_address
;
299 r_symbolnum
= rp
->r_symbolnum
;
300 r_extern
= rp
->r_extern
;
303 if (r_type
== SPARC_RELOC_PAIR
) {
304 fprintf(stderr
, "Stray SPARC_RELOC_PAIR entry ");
308 if(r_type
== SPARC_RELOC_HI22
||
309 r_type
== SPARC_RELOC_LO10
||
310 r_type
== SPARC_RELOC_HI22_SECTDIFF
||
311 r_type
== SPARC_RELOC_LO10_SECTDIFF
||
312 r_type
== SPARC_RELOC_SECTDIFF
){
315 if(rp_pair
->r_address
& R_SCATTERED
){
316 srp
= (struct scattered_relocation_info
*) rp_pair
;
317 other_half
= srp
->r_address
;
318 pair_r_type
= srp
->r_type
;
319 pair_r_value
= srp
->r_value
;
321 other_half
= rp_pair
->r_address
;
322 pair_r_type
= rp_pair
->r_type
;
324 if(pair_r_type
!= SPARC_RELOC_PAIR
){
325 fprintf(stderr
, "No SPARC_RELOC_PAIR relocation "
326 "entry after entry %u\n", i
);
335 if (r_type
== SPARC_RELOC_HI22
||
336 r_type
== SPARC_RELOC_LO10
||
337 r_type
== SPARC_RELOC_SECTDIFF
||
338 r_type
== SPARC_RELOC_HI22_SECTDIFF
||
339 r_type
== SPARC_RELOC_LO10_SECTDIFF
)
343 if (rp_pair
->r_address
& R_SCATTERED
) {
344 srp
= (struct scattered_relocation_info
*) rp_pair
;
345 pair_r_type
= srp
->r_type
;
347 pair_r_type
= rp_pair
->r_type
;
349 if (pair_r_type
== SPARC_RELOC_PAIR
) {
354 "no SPARC_RELOC_PAIR relocation entry after %u\n", i
);
361 /* Now get the reloc information if we located one */
363 if (reloc_found
&& (r_extern
== 1)) {
364 if ((uint32_t)symbols
[r_symbolnum
].n_un
.n_strx
>= strings_size
)
365 name
= "bad string offset";
367 name
= strings
+ symbols
[r_symbolnum
].n_un
.n_strx
;
370 case SPARC_RELOC_HI22
:
372 printf("%%hi(%s", name
);
374 printf("+0x%x)", (unsigned int) value
);
378 case SPARC_RELOC_LO10
:
379 value
|= other_half
<< 10;
380 printf("%%lo(%s", name
);
382 printf("+0x%x)", (unsigned int) value
);
386 case SPARC_RELOC_WDISP30
:
389 printf("+0x%x", (unsigned int) value
);
391 case SPARC_RELOC_WDISP22
:
394 printf("+0x%x", (unsigned int) value
);
404 if(r_type
== SPARC_RELOC_HI22
||
405 r_type
== SPARC_RELOC_HI22_SECTDIFF
)
407 else if(r_type
== SPARC_RELOC_LO10
||
408 r_type
== SPARC_RELOC_LO10_SECTDIFF
)
409 value
|= other_half
<< 10;
411 (r_type
!= SPARC_RELOC_HI22_SECTDIFF
&&
412 r_type
!= SPARC_RELOC_LO10_SECTDIFF
)){
413 offset
= value
- r_value
;
419 (r_type
== SPARC_RELOC_HI22_SECTDIFF
||
420 r_type
== SPARC_RELOC_LO10_SECTDIFF
)) {
421 if (r_type
== SPARC_RELOC_HI22_SECTDIFF
)
425 add
= guess_symbol (r_value
, sorted_symbols
,
426 nsorted_symbols
, verbose
);
427 sub
= guess_symbol (pair_r_value
, sorted_symbols
,
428 nsorted_symbols
, verbose
);
432 printf("0x%x", (unsigned int) r_value
);
437 printf("-0x%x", (unsigned int) pair_r_value
);
440 printf("+0x%x)", (unsigned int) offset
);
446 /* no reloc entry, so it's either a symbol or a label */
448 if (operand
== 'l' || operand
== 'L') {
450 The pc has already been added in the 'l' and 'L' cases by the caller.
451 if ((name = guess_symbol(pc + value, sorted_symbols,
452 nsorted_symbols, verbose)) != NULL)
454 if ((name
= guess_symbol(value
, sorted_symbols
,
455 nsorted_symbols
, verbose
)) != NULL
)
458 printf("0x%x", (unsigned int) value
);
460 /* possible symbol reference */
461 name
= guess_symbol(value
, sorted_symbols
, nsorted_symbols
, TRUE
);
464 case SPARC_RELOC_HI22
:
466 /* to print the correct value, we really should look ahead for
467 %lo portion of the immediate value and reconstruct it instead
468 of simply printing the already truncated %hi value only */
470 printf("%%hi(%s)", name
);
472 printf("%%hi(0x%x)", (unsigned int) value
);
474 case SPARC_RELOC_LO10
:
476 /* same here. Look at the last remembered %hi value and add it in */
478 printf("%%lo(%s)", name
);
480 printf("%%lo(0x%x)", (unsigned int) value
);
486 printf("0x%x", (unsigned int) value
);
497 enum byte_sex object_byte_sex
,
498 struct relocation_info
*relocs
,
500 struct nlist
*symbols
,
502 struct symbol
*sorted_symbols
,
503 uint32_t nsorted_symbols
,
505 uint32_t strings_size
,
506 uint32_t *indirect_symbols
,
507 uint32_t nindirect_symbols
,
508 struct load_command
*load_commands
,
513 enum byte_sex host_byte_sex
;
516 uint32_t sect_offset
;
517 union sparc_insn insn
;
518 struct sparc_opcode
*opcode
;
519 int imm_added_to_rs1
= 0; /* adding or or'ing imm13 into rs1? */
520 int found_plus
= 0; /* Found plus sign in args? */
521 int is_annulled
= 0; /* We have an annulled branch? */
523 static union sparc_insn sethi_insn
;
524 const char *indirect_symbol_name
;
528 if (!opcodes_sorted
) {
529 qsort ((char *) sparc_opcodes
, NUMOPCODES
,
530 sizeof (sparc_opcodes
[0]), compare_opcodes
);
534 sect_offset
= addr
- sect_addr
;
535 host_byte_sex
= get_host_byte_sex();
536 swapped
= host_byte_sex
!= object_byte_sex
;
538 if (left
< sizeof(uint32_t)) {
540 memcpy(&insn
, sect
, left
);
542 insn
.code
= SWAP_INT(insn
.code
);
543 printf(".long\t0x%08x\n", (unsigned int)insn
.code
);
545 printf("(end of section)\n");
549 memcpy(&insn
, sect
, sizeof(uint32_t));
551 insn
.code
= SWAP_INT(insn
.code
);
553 /* search through the opcode table */
554 for (i
=0; i
<NUMOPCODES
; ++i
) {
555 opcode
= &sparc_opcodes
[i
];
556 if ((opcode
->match
& insn
.code
) == opcode
->match
557 && (opcode
->lose
& insn
.code
) == 0) {
558 /* Can't do simple format if source and dest are different. */
559 /* This also takes care of the synthetic 'neg' instruction */
560 if ((insn
.rs1
!= insn
.rd
561 && strchr (opcode
->args
, 'r') != 0) ||
562 (insn
.rs2
!= insn
.rd
&&
563 strchr (opcode
->args
, 'u'))) {
572 if (i
>= NUMOPCODES
) {
573 printf(".long 0x%08x\n", (unsigned int)insn
.code
);
577 printf("%s", opcode
->name
);
579 /* Do we have an `add' or `or' instruction where rs1 is the same
580 as rsd, and which has the i bit set? */
581 /* Check for st instruction as well, as it's commonly used with %lo */
582 if ((opcode
->match
== 0x80102000 || /* or */
583 opcode
->match
== 0x80002000 || /* add */
584 opcode
->match
== 0xd0202000 ) /* st */
585 /* && insn.rs1 == insn.rd */)
586 imm_added_to_rs1
= 1;
588 if (opcode
->args
[0] != ',')
590 for (s
= opcode
->args
; *s
!= '\0'; ++s
) {
602 } /* switch on arg */
603 } /* while there are comma started args */
616 #define reg(n) printf("%%%s", reg_names[n])
635 #define freg(n) printf("%%%s", freg_names[n])
636 #define fregx(n) printf("%%%s", reg_names[((n) & ~1) | (((n) & 1) << 5)])
640 case 'v': /* double/even */
641 case 'V': /* quad/multiple of 4 */
648 case 'B': /* double/even */
649 case 'R': /* quad/multiple of 4 */
656 case 'H': /* double/even */
657 case 'J': /* quad/multiple of 4 */
663 #define creg(n) printf("%%c%u", (unsigned int) (n))
677 sethi_insn
.code
= insn
.code
; /* for later use */
678 SYM_PRINT(*s
,((int) insn
.imm22
<<10), sect_offset
);
682 /* We cannot trust the compiler to sign-extend
683 when extracting the bitfield, hence the shifts. */
684 int imm
= SEX (insn
.imm13
, 13);
686 /* Check to see whether we have a 1+i, and take
689 Note: because of the way we sort the table,
690 we will be matching 1+i rather than i+1,
691 so it is OK to assume that i is after +,
694 imm_added_to_rs1
= 1;
700 printf("%%asr%d", insn
.rs1
);
703 printf("%%asr%d", insn
.rd
);
706 SYM_PRINT(*s
,addr
+ ((insn
.disp30
& 0x3fffffff) << 2), sect_offset
);
708 indirect_symbol_name
= guess_indirect_symbol(
709 addr
+ ((insn
.disp30
& 0x3fffffff) << 2),
710 ncmds
, sizeofcmds
, load_commands
, object_byte_sex
, indirect_symbols
,
711 nindirect_symbols
, symbols
, NULL
, nsymbols
, strings
, strings_size
);
712 if(indirect_symbol_name
!= NULL
)
713 printf("\t; symbol stub for: %s", indirect_symbol_name
);
717 printf("%#x", (SEX (insn
.disp22
, 22)));
720 SYM_PRINT(*s
,addr
+ (SEX(insn
.disp22
, 22) << 2), sect_offset
);
723 printf("(%d)", (int) insn
.asi
);
752 /* If we are adding or or'ing something to rs1, then
753 check to see whether the previous instruction was
754 a sethi to the same register as in the sethi.
755 If so, attempt to print the result of the add or
756 or (in this context add and or do the same thing)
757 and its symbolic value. */
758 if (imm_added_to_rs1
) {
759 union sparc_insn prev_insn
;
761 /* Check if there is a pending sethi instruction. If so, check if
762 the insn uses the same r1 register - that's a good indication
763 this is the %lo we're waiting for. The prolem is that the
764 instruction containg the %lo may have been optimized away by
765 the assembler. There is also no telling how many intermediate
766 instructions the compiler (or human) has put between the
769 if (sethi_insn
.code
) /* got a pending one */
770 if (insn
.rs1
== sethi_insn
.rs1
) { /* getting closer */
771 /* SYM_PRINT(*s ,((int) insn.imm13), sect_offset); */
776 if ((sect_addr
- addr
) >= 8) // space before us this?
777 memcpy(&prev_insn
, sect
- 4, sizeof(uint32_t));
781 /* If it is a delayed branch, we need to look at the
782 instruction before the delayed branch. This handles
785 sethi %o1, %hi(_foo), %o1
787 or %o1, %lo(_foo), %o1
790 if (prev_insn
.code
/* && is_delayed_branch (prev_insn) */)
791 memcpy(&prev_insn
, sect
- 8, sizeof(uint32_t));
795 /* Is it sethi to the same register? */
796 if ((prev_insn
.code
& 0xc1c00000) == 0x01000000
797 && prev_insn
.rd
== insn
.rs1
) {
800 (0xFFFFFFFF & (int) prev_insn
.imm22
<< 10)
801 | SEX (insn
.imm13
, 13));
808 /* Compare opcodes A and B. */
811 compare_opcodes (a
, b
)
814 struct sparc_opcode
*op0
= (struct sparc_opcode
*) a
;
815 struct sparc_opcode
*op1
= (struct sparc_opcode
*) b
;
816 uint32_t match0
= op0
->match
, match1
= op1
->match
;
817 uint32_t lose0
= op0
->lose
, lose1
= op1
->lose
;
818 register unsigned int i
;
820 /* If a bit is set in both match and lose, there is something
821 wrong with the opcode table. */
824 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8x, %#.8x\n",
825 op0
->name
, match0
, lose0
);
826 op0
->lose
&= ~op0
->match
;
832 fprintf (stderr
, "Internal error: bad sparc-opcode.h: \"%s\", %#.8x, %#.8x\n",
833 op1
->name
, match1
, lose1
);
834 op1
->lose
&= ~op1
->match
;
838 /* Because the bits that are variable in one opcode are constant in
839 another, it is important to order the opcodes in the right order. */
840 for (i
= 0; i
< 32; ++i
)
843 int x0
= (match0
& x
) != 0;
844 int x1
= (match1
& x
) != 0;
850 for (i
= 0; i
< 32; ++i
)
853 int x0
= (lose0
& x
) != 0;
854 int x1
= (lose1
& x
) != 0;
860 /* They are functionally equal. So as long as the opcode table is
861 valid, we can put whichever one first we want, on aesthetic grounds. */
863 /* Our first aesthetic ground is that aliases defer to real insns. */
865 int alias_diff
= (op0
->flags
& F_ALIAS
) - (op1
->flags
& F_ALIAS
);
867 /* Put the one that isn't an alias first. */
871 /* Except for aliases, two "identical" instructions had
872 better have the same opcode. This is a sanity check on the table. */
873 i
= strcmp (op0
->name
, op1
->name
);
875 if (op0
->flags
& F_ALIAS
) /* If they're both aliases, be arbitrary. */
879 "Internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n",
880 op0
->name
, op1
->name
);
883 /* Fewer arguments are preferred. */
885 int length_diff
= strlen (op0
->args
) - strlen (op1
->args
);
886 if (length_diff
!= 0)
887 /* Put the one with fewer arguments first. */
891 /* Put 1+i before i+1. */
893 char *p0
= (char *) strchr(op0
->args
, '+');
894 char *p1
= (char *) strchr(op1
->args
, '+');
898 /* There is a plus in both operands. Note that a plus
899 sign cannot be the first character in args,
900 so the following [-1]'s are valid. */
901 if (p0
[-1] == 'i' && p1
[1] == 'i')
902 /* op0 is i+1 and op1 is 1+i, so op1 goes first. */
904 if (p0
[1] == 'i' && p1
[-1] == 'i')
905 /* op0 is 1+i and op1 is i+1, so op0 goes first. */
910 /* They are, as far as we can tell, identical.
911 Since qsort may have rearranged the table partially, there is
912 no way to tell which one was first in the opcode table as
913 written, so just say there are equal. */