subrepo asm-processor (#1212)

* yeet

* git subrepo clone git@github.com:simonlindholm/asm-processor.git tools/asm-processor

subrepo:
  subdir:   "tools/asm-processor"
  merged:   "bbd86ea1f"
upstream:
  origin:   "git@github.com:simonlindholm/asm-processor.git"
  branch:   "main"
  commit:   "bbd86ea1f"
git-subrepo:
  version:  "0.4.3"
  origin:   "https://github.com/ingydotnet/git-subrepo.git"
  commit:   "2f68596"
This commit is contained in:
Anghelo Carvajal 2023-03-17 01:16:30 -03:00 committed by GitHub
parent a17949e730
commit 58022571ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 3284 additions and 157 deletions

2
tools/asm-processor/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.o
*.py[cod]

View File

@ -0,0 +1,12 @@
; DO NOT EDIT (unless you know what you are doing)
;
; This subdirectory is a git "subrepo", and this file is maintained by the
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
;
[subrepo]
remote = git@github.com:simonlindholm/asm-processor.git
branch = main
commit = bbd86ea1faf84e6a7a0e101ab8068a00a3dfb2fc
parent = 8985197b6da23db874ac6e8a29ddec5636944bba
method = merge
cmdver = 0.4.3

View File

@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org>

View File

@ -0,0 +1,112 @@
# asm-processor
Pre-process .c files and post-process .o files to enable embedding MIPS assembly into IDO-compiled C.
## Usage
Let's say you have a file compiled with `-g` on the IDO compiler, that looks like this:
```c
float func4(void) {
"func4";
return 0.2f;
}
```
This script enables replacing it by:
```asm
GLOBAL_ASM(
.rdata
.word 0x66756e63 # func
.word 0x34000000 # 4\0\0\0
.late_rodata
glabel rv
.word 0x3e4ccccd # 0.2f
.text
glabel func4
lui $at, %hi(rv)
jr $ra
lwc1 $f0, %lo(rv)($at)
jr $ra
nop
jr $ra
nop
)
```
To compile the file, run `python3 build.py $CC -- $AS $ASFLAGS -- $CFLAGS -o out.o in.c`, where $CC points to an IDO binary (5.3/7.1 and recomp/qemu all supported), $AS is e.g. `mips-linux-gnu-as`, $ASFLAGS e.g. `-march=vr4300 -mabi=32` and $CFLAGS e.g. `-Wab,-r4300_mul -non_shared -G 0 -Xcpluscomm -g`. build.py may be customized as needed.
In addition to an .o file, build.py also generates a .d file with Makefile dependencies for .s files referenced by the input .c file.
This functionality may be removed if not needed.
Reading assembly from file is also supported, by either `GLOBAL_ASM("file.s")` or `#pragma GLOBAL_ASM("file.s")`.
### What is supported?
`.text`, `.data`, `.bss` and `.rodata` sections, `.word`/`.incbin`, `.ascii`/`.asciz`, and `-g`, `-g3`, `-O1`, `-O2`, `-framepointer` and `-mips1`/`-mips2` flags to the IDO compiler.
### What is not supported?
* complicated assembly (.ifdef, macro declarations/calls other than `glabel`, pseudo-instructions that expand to several real instructions)
* non-IDO compilers
* `-O3` (due to function reordering)
C `#ifdef`s only work outside of `GLOBAL_ASM` calls, but is otherwise able to replace `.ifdef`.
### What's up with "late rodata"?
The IDO compiler emits rodata in two passes: first array/string contents, then large literals/switch jump tables.
Data declared within `.rdata`/`.section .rodata` will end up in the first half, and `.late_rodata`/`.section .late_rodata` in the second half.
### How does it work?
It's a bit of a hack!
The basic idea is replace `GLOBAL_ASM` blocks with dummy C functions/global vars of the same sections sizes as the assembly.
Then the C file gets compiled, and the dummy contents overwritten with the injected assembly.
To accomplish this, asm-processor has logic for guessing the size of assembly contents
(which assumes the assembly isn't too complicated, e.g. no macros),
and for emitting C code of exact sizes for a bunch of different IDO compiler flags.
The assembler code is padded with nops to line it up with its correct position in the C;
this allows C and asm ELF files to be merged easily without having to fix up e.g. symbol addresses.
The most difficult part is `late_rodata`, which is hard to create programmatically.
asm-processor does that by emitting code that uses dummy float literals/double literals/jump tables,
assembles the late_rodata at another location of the .rodata section, then overwrites the dummy rodata.
This does require some movement of symbols and relocations, and quite a bit of care in what code to
emit and how to preserve .double alignment.
It's worth noting some alternative ways in which asm-processor would have been implemented:
- One idea to get rid of the C/asm size estimations is to emit arbitrary code, and then move code,
symbols and relocations to the correct place after the sizes are known.
Given the machinery for `late_rodata` this wouldn't have been too difficult, and it would have the upside of improved portability.
There is a big downside, however: using dummy code of incorrect size throws off alignment and can introduce unintended padding.
Fixing this would require running multiple passes of asm-processor, with one compile per `ASM_GLOBAL`.
- Another idea is to run the compiler with -S to emit assembly, modify the emitted assembly, then run the assembler
(which in IDO's case may perform additional instruction reordering etc.).
This option has not been investigated in much detail, and would perhaps be superior to the current implementation.
It does have a few unknowns to it, e.g. instruction encoding differences between GNU `as` and IDO's assembler,
how to avoid reordering the injected assembly, and how .rodata/.late_rodata are implemented.
### Testing
There are a few tests to ensure you don't break anything when hacking on asm-processor: `./run-tests.sh` should exit without output if they pass, or else output a diff from previous to new version.
Tests need the environment variable `MIPS_CC` set to point to the IDO 7.1 compiler, with Pascal support enabled.
For example if asm-processor is cloned in the same directory as [ido static recomp](https://github.com/decompals/ido-static-recomp) and the working directory is asm-processor, tests can be run using:
```sh
MIPS_CC=../ido-static-recomp/build/7.1/out/cc ./run-tests.sh
```
Or using [qemu-irix](https://github.com/zeldaret/oot/releases/tag/0.1q) (don't forget `chmod u+x qemu-irix`) to emulate IDO:
```sh
MIPS_CC='./qemu-irix -silent -L ../ido-static-recomp/ido/7.1/ ../ido-static-recomp/ido/7.1/usr/bin/cc' ./run-tests.sh
```
To skip running Pascal tests, remove the `tests/*.p` glob from `run-tests.sh`.

View File

@ -0,0 +1,5 @@
#!/usr/bin/env bash
for A in "$@"; do
OBJDUMPFLAGS="-srt"
./compile-test.sh "$A" && mips-linux-gnu-objdump $OBJDUMPFLAGS "${A%.*}.o" > "${A%.*}.objdump"
done

View File

@ -85,6 +85,18 @@ MIPS_DEBUG_ST_STATIC = 2
MIPS_DEBUG_ST_STATIC_PROC = 14
class ElfFormat:
def __init__(self, is_big_endian):
self.is_big_endian = is_big_endian
self.struct_char = ">" if is_big_endian else "<"
def pack(self, fmt, *args):
return struct.pack(self.struct_char + fmt, *args)
def unpack(self, fmt, data):
return struct.unpack(self.struct_char + fmt, data)
class ElfHeader:
"""
typedef struct {
@ -107,9 +119,9 @@ class ElfHeader:
def __init__(self, data):
self.e_ident = data[:EI_NIDENT]
self.e_type, self.e_machine, self.e_version, self.e_entry, self.e_phoff, self.e_shoff, self.e_flags, self.e_ehsize, self.e_phentsize, self.e_phnum, self.e_shentsize, self.e_shnum, self.e_shstrndx = struct.unpack('>HHIIIIIHHHHHH', data[EI_NIDENT:])
assert self.e_ident[EI_CLASS] == 1 # 32-bit
assert self.e_ident[EI_DATA] == 2 # big-endian
self.fmt = ElfFormat(is_big_endian=(self.e_ident[EI_DATA] == 2))
self.e_type, self.e_machine, self.e_version, self.e_entry, self.e_phoff, self.e_shoff, self.e_flags, self.e_ehsize, self.e_phentsize, self.e_phnum, self.e_shentsize, self.e_shnum, self.e_shstrndx = self.fmt.unpack('HHIIIIIHHHHHH', data[EI_NIDENT:])
assert self.e_type == 1 # relocatable
assert self.e_machine == 8 # MIPS I Architecture
assert self.e_phoff == 0 # no program header
@ -117,7 +129,7 @@ class ElfHeader:
assert self.e_shstrndx != SHN_UNDEF
def to_bin(self):
return self.e_ident + struct.pack('>HHIIIIIHHHHHH', self.e_type,
return self.e_ident + self.fmt.pack('HHIIIIIHHHHHH', self.e_type,
self.e_machine, self.e_version, self.e_entry, self.e_phoff,
self.e_shoff, self.e_flags, self.e_ehsize, self.e_phentsize,
self.e_phnum, self.e_shentsize, self.e_shnum, self.e_shstrndx)
@ -135,8 +147,9 @@ class Symbol:
} Elf32_Sym;
"""
def __init__(self, data, strtab, name=None):
self.st_name, self.st_value, self.st_size, st_info, self.st_other, self.st_shndx = struct.unpack('>IIIBBH', data)
def __init__(self, fmt, data, strtab, name=None):
self.fmt = fmt
self.st_name, self.st_value, self.st_size, st_info, self.st_other, self.st_shndx = fmt.unpack('IIIBBH', data)
assert self.st_shndx != SHN_XINDEX, "too many sections (SHN_XINDEX not supported)"
self.bind = st_info >> 4
self.type = st_info & 15
@ -144,31 +157,32 @@ class Symbol:
self.visibility = self.st_other & 3
@staticmethod
def from_parts(st_name, st_value, st_size, st_info, st_other, st_shndx, strtab, name):
header = struct.pack('>IIIBBH', st_name, st_value, st_size, st_info, st_other, st_shndx)
return Symbol(header, strtab, name)
def from_parts(fmt, st_name, st_value, st_size, st_info, st_other, st_shndx, strtab, name):
header = fmt.pack('IIIBBH', st_name, st_value, st_size, st_info, st_other, st_shndx)
return Symbol(fmt, header, strtab, name)
def to_bin(self):
st_info = (self.bind << 4) | self.type
return struct.pack('>IIIBBH', self.st_name, self.st_value, self.st_size, st_info, self.st_other, self.st_shndx)
return self.fmt.pack('IIIBBH', self.st_name, self.st_value, self.st_size, st_info, self.st_other, self.st_shndx)
class Relocation:
def __init__(self, data, sh_type):
def __init__(self, fmt, data, sh_type):
self.fmt = fmt
self.sh_type = sh_type
if sh_type == SHT_REL:
self.r_offset, self.r_info = struct.unpack('>II', data)
self.r_offset, self.r_info = fmt.unpack('II', data)
else:
self.r_offset, self.r_info, self.r_addend = struct.unpack('>III', data)
self.r_offset, self.r_info, self.r_addend = fmt.unpack('III', data)
self.sym_index = self.r_info >> 8
self.rel_type = self.r_info & 0xff
def to_bin(self):
self.r_info = (self.sym_index << 8) | self.rel_type
if self.sh_type == SHT_REL:
return struct.pack('>II', self.r_offset, self.r_info)
return self.fmt.pack('II', self.r_offset, self.r_info)
else:
return struct.pack('>III', self.r_offset, self.r_info, self.r_addend)
return self.fmt.pack('III', self.r_offset, self.r_info, self.r_addend)
class Section:
@ -187,8 +201,9 @@ class Section:
} Elf32_Shdr;
"""
def __init__(self, header, data, index):
self.sh_name, self.sh_type, self.sh_flags, self.sh_addr, self.sh_offset, self.sh_size, self.sh_link, self.sh_info, self.sh_addralign, self.sh_entsize = struct.unpack('>IIIIIIIIII', header)
def __init__(self, fmt, header, data, index):
self.fmt = fmt
self.sh_name, self.sh_type, self.sh_flags, self.sh_addr, self.sh_offset, self.sh_size, self.sh_link, self.sh_info, self.sh_addralign, self.sh_entsize = fmt.unpack('IIIIIIIIII', header)
assert not self.sh_flags & SHF_LINK_ORDER
if self.sh_entsize != 0:
assert self.sh_size % self.sh_entsize == 0
@ -200,9 +215,9 @@ class Section:
self.relocated_by = []
@staticmethod
def from_parts(sh_name, sh_type, sh_flags, sh_link, sh_info, sh_addralign, sh_entsize, data, index):
header = struct.pack('>IIIIIIIIII', sh_name, sh_type, sh_flags, 0, 0, len(data), sh_link, sh_info, sh_addralign, sh_entsize)
return Section(header, data, index)
def from_parts(fmt, sh_name, sh_type, sh_flags, sh_link, sh_info, sh_addralign, sh_entsize, data, index):
header = fmt.pack('IIIIIIIIII', sh_name, sh_type, sh_flags, 0, 0, len(data), sh_link, sh_info, sh_addralign, sh_entsize)
return Section(fmt, header, data, index)
def lookup_str(self, index):
assert self.sh_type == SHT_STRTAB
@ -222,7 +237,7 @@ class Section:
def header_to_bin(self):
if self.sh_type != SHT_NOBITS:
self.sh_size = len(self.data)
return struct.pack('>IIIIIIIIII', self.sh_name, self.sh_type, self.sh_flags, self.sh_addr, self.sh_offset, self.sh_size, self.sh_link, self.sh_info, self.sh_addralign, self.sh_entsize)
return self.fmt.pack('IIIIIIIIII', self.sh_name, self.sh_type, self.sh_flags, self.sh_addr, self.sh_offset, self.sh_size, self.sh_link, self.sh_info, self.sh_addralign, self.sh_entsize)
def late_init(self, sections):
if self.sh_type == SHT_SYMTAB:
@ -251,14 +266,14 @@ class Section:
self.strtab = sections[self.sh_link]
entries = []
for i in range(0, self.sh_size, self.sh_entsize):
entries.append(Symbol(self.data[i:i+self.sh_entsize], self.strtab))
entries.append(Symbol(self.fmt, self.data[i:i+self.sh_entsize], self.strtab))
self.symbol_entries = entries
def init_relocs(self):
assert self.is_rel()
entries = []
for i in range(0, self.sh_size, self.sh_entsize):
entries.append(Relocation(self.data[i:i+self.sh_entsize], self.sh_type))
entries.append(Relocation(self.fmt, self.data[i:i+self.sh_entsize], self.sh_type))
self.relocations = entries
def local_symbols(self):
@ -281,9 +296,9 @@ class Section:
hdrr_cbOptOffset, hdrr_iauxMax, hdrr_cbAuxOffset, hdrr_issMax, \
hdrr_cbSsOffset, hdrr_issExtMax, hdrr_cbSsExtOffset, hdrr_ifdMax, \
hdrr_cbFdOffset, hdrr_crfd, hdrr_cbRfdOffset, hdrr_iextMax, \
hdrr_cbExtOffset = struct.unpack(">HHIIIIIIIIIIIIIIIIIIIIIII", self.data[0:0x60])
hdrr_cbExtOffset = self.fmt.unpack("HHIIIIIIIIIIIIIIIIIIIIIII", self.data[0:0x60])
assert hdrr_magic == 0x7009 , "Invalid magic value for .mdebug symbolic header"
assert hdrr_magic == 0x7009, "Invalid magic value for .mdebug symbolic header"
hdrr_cbLineOffset += shift_by
hdrr_cbDnOffset += shift_by
@ -297,7 +312,7 @@ class Section:
hdrr_cbRfdOffset += shift_by
hdrr_cbExtOffset += shift_by
new_data[0:0x60] = struct.pack(">HHIIIIIIIIIIIIIIIIIIIIIII", hdrr_magic, hdrr_vstamp, hdrr_ilineMax, hdrr_cbLine, \
new_data[0:0x60] = self.fmt.pack("HHIIIIIIIIIIIIIIIIIIIIIII", hdrr_magic, hdrr_vstamp, hdrr_ilineMax, hdrr_cbLine, \
hdrr_cbLineOffset, hdrr_idnMax, hdrr_cbDnOffset, hdrr_ipdMax, \
hdrr_cbPdOffset, hdrr_isymMax, hdrr_cbSymOffset, hdrr_ioptMax, \
hdrr_cbOptOffset, hdrr_iauxMax, hdrr_cbAuxOffset, hdrr_issMax, \
@ -313,15 +328,16 @@ class ElfFile:
assert data[:4] == b'\x7fELF', "not an ELF file"
self.elf_header = ElfHeader(data[0:52])
self.fmt = self.elf_header.fmt
offset, size = self.elf_header.e_shoff, self.elf_header.e_shentsize
null_section = Section(data[offset:offset + size], data, 0)
null_section = Section(self.fmt, data[offset:offset + size], data, 0)
num_sections = self.elf_header.e_shnum or null_section.sh_size
self.sections = [null_section]
for i in range(1, num_sections):
ind = offset + i * size
self.sections.append(Section(data[ind:ind + size], data, i))
self.sections.append(Section(self.fmt, data[ind:ind + size], data, i))
symtab = None
for s in self.sections:
@ -345,7 +361,7 @@ class ElfFile:
def add_section(self, name, sh_type, sh_flags, sh_link, sh_info, sh_addralign, sh_entsize, data):
shstr = self.sections[self.elf_header.e_shstrndx]
sh_name = shstr.add_str(name)
s = Section.from_parts(sh_name=sh_name, sh_type=sh_type,
s = Section.from_parts(self.fmt, sh_name=sh_name, sh_type=sh_type,
sh_flags=sh_flags, sh_link=sh_link, sh_info=sh_info,
sh_addralign=sh_addralign, sh_entsize=sh_entsize, data=data,
index=len(self.sections))
@ -421,15 +437,18 @@ class Failure(Exception):
class GlobalState:
def __init__(self, min_instr_count, skip_instr_count, use_jtbl_for_rodata, mips1):
def __init__(self, min_instr_count, skip_instr_count, use_jtbl_for_rodata, prelude_if_late_rodata, mips1, pascal):
# A value that hopefully never appears as a 32-bit rodata constant (or we
# miscompile late rodata). Increases by 1 in each step.
self.late_rodata_hex = 0xE0123456
self.valuectr = 0
self.namectr = 0
self.min_instr_count = min_instr_count
self.skip_instr_count = skip_instr_count
self.use_jtbl_for_rodata = use_jtbl_for_rodata
self.prelude_if_late_rodata = prelude_if_late_rodata
self.mips1 = mips1
self.pascal = pascal
def next_late_rodata_hex(self):
dummy_bytes = struct.pack('>I', self.late_rodata_hex)
@ -443,6 +462,36 @@ class GlobalState:
self.namectr += 1
return '_asmpp_{}{}'.format(cat, self.namectr)
def func_prologue(self, name):
if self.pascal:
return " ".join([
"procedure {}();".format(name),
"type",
" pi = ^integer;",
" pf = ^single;",
" pd = ^double;",
"var",
" vi: pi;",
" vf: pf;",
" vd: pd;",
"begin",
" vi := vi;",
" vf := vf;",
" vd := vd;",
])
else:
return 'void {}(void) {{'.format(name)
def func_epilogue(self):
if self.pascal:
return "end;"
else:
return "}"
def pascal_assignment(self, tp, val):
self.valuectr += 1
address = (8 * self.valuectr) & 0x7FFF
return 'v{} := p{}({}); v{}^ := {};'.format(tp, tp, address, tp, val)
Function = namedtuple('Function', ['text_glabels', 'asm_conts', 'late_rodata_dummy_bytes', 'jtbl_rodata_size', 'late_rodata_asm_conts', 'fn_desc', 'data'])
@ -476,6 +525,7 @@ class GlobalAsmBlock:
def count_quoted_size(self, line, z, real_line, output_enc):
line = line.encode(output_enc).decode('latin1')
in_quote = False
has_comma = True
num_parts = 0
ret = 0
i = 0
@ -486,10 +536,15 @@ class GlobalAsmBlock:
if not in_quote:
if c == '"':
in_quote = True
if z and not has_comma:
self.fail(".asciiz with glued strings is not supported due to GNU as version diffs")
num_parts += 1
elif c == ',':
has_comma = True
else:
if c == '"':
in_quote = False
has_comma = False
continue
ret += 1
if c != '\\':
@ -554,7 +609,7 @@ class GlobalAsmBlock:
self.text_glabels.append(line.split()[1])
if not line:
pass # empty line
elif line.startswith('glabel ') or (' ' not in line and line.endswith(':')):
elif line.startswith('glabel ') or line.startswith('dlabel ') or line.startswith('endlabel ') or (' ' not in line and line.endswith(':')):
pass # label
elif line.startswith('.section') or line in ['.text', '.data', '.rdata', '.rodata', '.bss', '.late_rodata']:
# section change
@ -574,7 +629,7 @@ class GlobalAsmBlock:
changed_section = True
elif line.startswith('.incbin'):
self.add_sized(int(line.split(',')[-1].strip(), 0), real_line)
elif line.startswith('.word') or line.startswith('.float'):
elif line.startswith('.word') or line.startswith('.gpword') or line.startswith('.float'):
self.align4()
self.add_sized(4 * len(line.split(',')), real_line)
elif line.startswith('.double'):
@ -651,7 +706,12 @@ class GlobalAsmBlock:
skip_next = False
needs_double = (self.late_rodata_alignment != 0)
extra_mips1_nop = False
jtbl_size = 11 if state.mips1 else 9
if state.pascal:
jtbl_size = 9 if state.mips1 else 8
jtbl_min_rodata_size = 2
else:
jtbl_size = 11 if state.mips1 else 9
jtbl_min_rodata_size = 5
for i in range(size):
if skip_next:
skip_next = False
@ -668,9 +728,15 @@ class GlobalAsmBlock:
# - we have at least 10 more instructions to go in this function (otherwise our
# function size computation will be wrong since the delay slot goes unused)
if (not needs_double and state.use_jtbl_for_rodata and i >= 1 and
size - i >= 5 and num_instr - len(late_rodata_fn_output) >= jtbl_size + 1):
cases = " ".join("case {}:".format(case) for case in range(size - i))
late_rodata_fn_output.append("switch (*(volatile int*)0) { " + cases + " ; }")
size - i >= jtbl_min_rodata_size and
num_instr - len(late_rodata_fn_output) >= jtbl_size + 1):
if state.pascal:
cases = " ".join("{}: ;".format(case) for case in range(size - i))
line = "case 0 of " + cases + " otherwise end;"
else:
cases = " ".join("case {}:".format(case) for case in range(size - i))
line = "switch (*(volatile int*)0) { " + cases + " ; }"
late_rodata_fn_output.append(line)
late_rodata_fn_output.extend([""] * (jtbl_size - 1))
jtbl_rodata_size = (size - i) * 4
extra_mips1_nop = i != 2
@ -681,7 +747,11 @@ class GlobalAsmBlock:
dummy_bytes2 = state.next_late_rodata_hex()
late_rodata_dummy_bytes.append(dummy_bytes2)
fval, = struct.unpack('>d', dummy_bytes + dummy_bytes2)
late_rodata_fn_output.append('*(volatile double*)0 = {};'.format(fval))
if state.pascal:
line = state.pascal_assignment('d', fval)
else:
line = '*(volatile double*)0 = {};'.format(fval)
late_rodata_fn_output.append(line)
skip_next = True
needs_double = False
if state.mips1:
@ -691,7 +761,11 @@ class GlobalAsmBlock:
extra_mips1_nop = False
else:
fval, = struct.unpack('>f', dummy_bytes)
late_rodata_fn_output.append('*(volatile float*)0 = {}f;'.format(fval))
if state.pascal:
line = state.pascal_assignment('f', fval)
else:
line = '*(volatile float*)0 = {}f;'.format(fval)
late_rodata_fn_output.append(line)
extra_mips1_nop = True
late_rodata_fn_output.append('')
late_rodata_fn_output.append('')
@ -701,8 +775,8 @@ class GlobalAsmBlock:
text_name = None
if self.fn_section_sizes['.text'] > 0 or late_rodata_fn_output:
text_name = state.make_name('func')
src[0] = 'void {}(void) {{'.format(text_name)
src[self.num_lines] = '}'
src[0] = state.func_prologue(text_name)
src[self.num_lines] = state.func_epilogue()
instr_count = self.fn_section_sizes['.text'] // 4
if instr_count < state.min_instr_count:
self.fail("too short .text block")
@ -710,6 +784,7 @@ class GlobalAsmBlock:
tot_skipped = 0
fn_emitted = 0
fn_skipped = 0
skipping = True
rodata_stack = late_rodata_fn_output[::-1]
for (line, count) in self.fn_ins_inds:
for _ in range(count):
@ -718,16 +793,28 @@ class GlobalAsmBlock:
# Don't let functions become too large. When a function reaches 284
# instructions, and -O2 -framepointer flags are passed, the IRIX
# compiler decides it is a great idea to start optimizing more.
# Also, Pascal cannot handle too large functions before it runs out
# of unique statements to write.
fn_emitted = 0
fn_skipped = 0
src[line] += ' }} void {}(void) {{ '.format(state.make_name('large_func'))
if fn_skipped < state.skip_instr_count:
skipping = True
src[line] += (' ' + state.func_epilogue() + ' ' +
state.func_prologue(state.make_name('large_func')) + ' ')
if (
skipping and
fn_skipped < state.skip_instr_count +
(state.prelude_if_late_rodata if rodata_stack else 0)
):
fn_skipped += 1
tot_skipped += 1
elif rodata_stack:
src[line] += rodata_stack.pop()
else:
src[line] += '*(volatile int*)0 = 0;'
skipping = False
if rodata_stack:
src[line] += rodata_stack.pop()
elif state.pascal:
src[line] += state.pascal_assignment('i', '0')
else:
src[line] += '*(volatile int*)0 = 0;'
tot_emitted += 1
fn_emitted += 1
if rodata_stack:
@ -741,16 +828,24 @@ class GlobalAsmBlock:
rodata_name = None
if self.fn_section_sizes['.rodata'] > 0:
if state.pascal:
self.fail(".rodata isn't supported with Pascal for now")
rodata_name = state.make_name('rodata')
src[self.num_lines] += ' const char {}[{}] = {{1}};'.format(rodata_name, self.fn_section_sizes['.rodata'])
data_name = None
if self.fn_section_sizes['.data'] > 0:
data_name = state.make_name('data')
src[self.num_lines] += ' char {}[{}] = {{1}};'.format(data_name, self.fn_section_sizes['.data'])
if state.pascal:
line = ' var {}: packed array[1..{}] of char := [otherwise: 0];'.format(data_name, self.fn_section_sizes['.data'])
else:
line = ' char {}[{}] = {{1}};'.format(data_name, self.fn_section_sizes['.data'])
src[self.num_lines] += line
bss_name = None
if self.fn_section_sizes['.bss'] > 0:
if state.pascal:
self.fail(".bss isn't supported with Pascal")
bss_name = state.make_name('bss')
src[self.num_lines] += ' char {}[{}];'.format(bss_name, self.fn_section_sizes['.bss'])
@ -775,43 +870,55 @@ float_regexpr = re.compile(r"[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?f")
def repl_float_hex(m):
return str(struct.unpack(">I", struct.pack(">f", float(m.group(0).strip().rstrip("f"))))[0])
def parse_source(f, opt, framepointer, mips1, input_enc, output_enc, out_dependencies, print_source=None):
if opt in ['O2', 'O1']:
if framepointer:
Opts = namedtuple('Opts', ['opt', 'framepointer', 'mips1', 'kpic', 'pascal', 'input_enc', 'output_enc'])
def parse_source(f, opts, out_dependencies, print_source=None):
if opts.opt in ['O1', 'O2']:
if opts.framepointer:
min_instr_count = 6
skip_instr_count = 5
else:
min_instr_count = 2
skip_instr_count = 1
elif opt == 'O0':
if framepointer:
elif opts.opt == 'O0':
if opts.framepointer:
min_instr_count = 8
skip_instr_count = 8
else:
min_instr_count = 4
skip_instr_count = 4
elif opt == 'g':
if framepointer:
elif opts.opt == 'g':
if opts.framepointer:
min_instr_count = 7
skip_instr_count = 7
else:
min_instr_count = 4
skip_instr_count = 4
else:
if opt != 'g3':
raise Failure("must pass one of -g, -O0, -O1, -O2, -O2 -g3")
if framepointer:
elif opts.opt == 'g3':
if opts.framepointer:
min_instr_count = 4
skip_instr_count = 4
else:
min_instr_count = 2
skip_instr_count = 2
else:
raise Failure("must pass one of -g, -O0, -O1, -O2, -O2 -g3")
prelude_if_late_rodata = 0
if opts.kpic:
# Without optimizations, the PIC prelude always takes up 3 instructions.
# With optimizations, the prelude is optimized out if there's no late rodata.
if opts.opt in ('g3', 'O2'):
prelude_if_late_rodata = 3
else:
min_instr_count += 3
skip_instr_count += 3
use_jtbl_for_rodata = False
if opt in ['O2', 'g3'] and not framepointer:
if opts.opt in ['O2', 'g3'] and not opts.framepointer and not opts.kpic:
use_jtbl_for_rodata = True
state = GlobalState(min_instr_count, skip_instr_count, use_jtbl_for_rodata, mips1)
state = GlobalState(min_instr_count, skip_instr_count, use_jtbl_for_rodata, prelude_if_late_rodata, opts.mips1, opts.pascal)
output_enc = opts.output_enc
global_asm = None
asm_functions = []
@ -848,7 +955,7 @@ def parse_source(f, opt, framepointer, mips1, input_enc, output_enc, out_depende
fname = line[line.index('(') + 2 : -2]
out_dependencies.append(fname)
global_asm = GlobalAsmBlock(fname)
with open(fname, encoding=input_enc) as f:
with open(fname, encoding=opts.input_enc) as f:
for line2 in f:
global_asm.process_line(line2.rstrip(), output_enc)
src, fn = global_asm.finish(state)
@ -870,8 +977,8 @@ def parse_source(f, opt, framepointer, mips1, input_enc, output_enc, out_depende
fname = os.path.join(fpath, line[line.index(' ') + 2 : -1])
out_dependencies.append(fname)
include_src = StringIO()
with open(fname, encoding=input_enc) as include_file:
parse_source(include_file, opt, framepointer, mips1, input_enc, output_enc, out_dependencies, include_src)
with open(fname, encoding=opts.input_enc) as include_file:
parse_source(include_file, opts, out_dependencies, include_src)
include_src.write('#line ' + str(line_no + 1) + ' "' + f.name + '"')
output_lines[-1] = include_src.getvalue()
include_src.close()
@ -891,6 +998,7 @@ def parse_source(f, opt, framepointer, mips1, input_enc, output_enc, out_depende
for line in output_lines:
print_source.write(line + '\n')
else:
newline_encoded = "\n".encode(output_enc)
for line in output_lines:
try:
line_encoded = line.encode(output_enc)
@ -899,18 +1007,18 @@ def parse_source(f, opt, framepointer, mips1, input_enc, output_enc, out_depende
print("The line:", line)
print("The line, utf-8-encoded:", line.encode("utf-8"))
raise
print_source.write(line_encoded + b'\n')
print_source.write(line_encoded)
print_source.write(newline_encoded)
print_source.flush()
if print_source != sys.stdout.buffer:
print_source.close()
return asm_functions
def fixup_objfile(objfile_name, functions, asm_prelude, assembler, output_enc, drop_mdebug_gptab):
def fixup_objfile(objfile_name, functions, asm_prelude, assembler, output_enc, drop_mdebug_gptab, convert_statics):
SECTIONS = ['.data', '.text', '.rodata', '.bss']
with open(objfile_name, 'rb') as f:
objfile = ElfFile(f.read())
fmt = objfile.fmt
prev_locs = {
'.text': 0,
@ -949,6 +1057,11 @@ def fixup_objfile(objfile_name, functions, asm_prelude, assembler, output_enc, d
loc = loc[1]
prev_loc = prev_locs[sectype]
if loc < prev_loc:
# If the dummy C generates too little asm, and we have two
# consecutive GLOBAL_ASM blocks, we detect that error here.
# On the other hand, if it generates too much, we don't have
# a good way of discovering that error: it's indistinguishable
# from a static symbol occurring after the GLOBAL_ASM block.
raise Failure("Wrongly computed size for section {} (diff {}). This is an asm-processor bug!".format(sectype, prev_loc- loc))
if loc != prev_loc:
asm.append('.section ' + sectype)
@ -958,7 +1071,7 @@ def fixup_objfile(objfile_name, functions, asm_prelude, assembler, output_enc, d
else:
asm.append('.space {}'.format(loc - prev_loc))
to_copy[sectype].append((loc, size, temp_name, function.fn_desc))
if function.text_glabels:
if function.text_glabels and sectype == '.text':
func_sizes[function.text_glabels[0]] = size
prev_locs[sectype] = loc + size
if not ifdefed:
@ -980,7 +1093,10 @@ def fixup_objfile(objfile_name, functions, asm_prelude, assembler, output_enc, d
if any(late_rodata_asm):
late_rodata_source_name_start = '_asmpp_late_rodata_start'
late_rodata_source_name_end = '_asmpp_late_rodata_end'
asm.append('.rdata')
asm.append('.section .late_rodata')
# Put some padding at the start to avoid conflating symbols with
# references to the whole section.
asm.append('.word 0, 0')
asm.append('glabel {}'.format(late_rodata_source_name_start))
for conts in late_rodata_asm:
asm.extend(conts)
@ -1011,11 +1127,12 @@ def fixup_objfile(objfile_name, functions, asm_prelude, assembler, output_enc, d
# Unify reginfo sections
target_reginfo = objfile.find_section('.reginfo')
source_reginfo_data = list(asm_objfile.find_section('.reginfo').data)
data = list(target_reginfo.data)
for i in range(20):
data[i] |= source_reginfo_data[i]
target_reginfo.data = bytes(data)
if target_reginfo is not None:
source_reginfo_data = list(asm_objfile.find_section('.reginfo').data)
data = list(target_reginfo.data)
for i in range(20):
data[i] |= source_reginfo_data[i]
target_reginfo.data = bytes(data)
# Move over section contents
modified_text_positions = set()
@ -1052,7 +1169,7 @@ def fixup_objfile(objfile_name, functions, asm_prelude, assembler, output_enc, d
# of another way of doing it.
moved_late_rodata = {}
if any(all_late_rodata_dummy_bytes) or any(all_jtbl_rodata_size):
source = asm_objfile.find_section('.rodata')
source = asm_objfile.find_section('.late_rodata')
target = objfile.find_section('.rodata')
source_pos = asm_objfile.symtab.find_symbol_in_section(late_rodata_source_name_start, source)
source_end = asm_objfile.symtab.find_symbol_in_section(late_rodata_source_name_end, source)
@ -1061,6 +1178,8 @@ def fixup_objfile(objfile_name, functions, asm_prelude, assembler, output_enc, d
new_data = list(target.data)
for dummy_bytes_list, jtbl_rodata_size in zip(all_late_rodata_dummy_bytes, all_jtbl_rodata_size):
for index, dummy_bytes in enumerate(dummy_bytes_list):
if not fmt.is_big_endian:
dummy_bytes = dummy_bytes[::-1]
pos = target.data.index(dummy_bytes, last_rodata_pos)
# This check is nice, but makes time complexity worse for large files:
if SLOW_CHECKS and target.data.find(dummy_bytes, pos + 4) != -1:
@ -1096,7 +1215,7 @@ def fixup_objfile(objfile_name, functions, asm_prelude, assembler, output_enc, d
# Find relocated symbols
relocated_symbols = set()
for sectype in SECTIONS:
for sectype in SECTIONS + ['.late_rodata']:
for obj in [asm_objfile, objfile]:
sec = obj.find_section(sectype)
if sec is None:
@ -1106,50 +1225,60 @@ def fixup_objfile(objfile_name, functions, asm_prelude, assembler, output_enc, d
relocated_symbols.add(obj.symtab.symbol_entries[rel.sym_index])
# Move over symbols, deleting the temporary function labels.
# Sometimes this naive procedure results in duplicate symbols, or UNDEF
# symbols that are also defined the same .o file. Hopefully that's fine.
# Skip over local symbols that aren't relocated against, to avoid
# conflicts.
new_local_syms = [s for s in objfile.symtab.local_symbols() if not is_temp_name(s.name)]
new_global_syms = [s for s in objfile.symtab.global_symbols() if not is_temp_name(s.name)]
# Skip over new local symbols that aren't relocated against, to
# avoid conflicts.
empty_symbol = objfile.symtab.symbol_entries[0]
new_syms = [s for s in objfile.symtab.symbol_entries[1:] if not is_temp_name(s.name)]
for i, s in enumerate(asm_objfile.symtab.symbol_entries):
is_local = (i < asm_objfile.symtab.sh_info)
if is_local and s not in relocated_symbols:
continue
if is_temp_name(s.name):
assert s not in relocated_symbols
continue
if s.st_shndx not in [SHN_UNDEF, SHN_ABS]:
section_name = asm_objfile.sections[s.st_shndx].name
if section_name not in SECTIONS:
raise Failure("generated assembly .o must only have symbols for .text, .data, .rodata, ABS and UNDEF, but found " + section_name)
s.st_shndx = objfile.find_section(section_name).index
target_section_name = section_name
if section_name == ".late_rodata":
target_section_name = ".rodata"
elif section_name not in SECTIONS:
raise Failure("generated assembly .o must only have symbols for .text, .data, .rodata, .late_rodata, ABS and UNDEF, but found " + section_name)
objfile_section = objfile.find_section(target_section_name)
if objfile_section is None:
raise Failure("generated assembly .o has section that real objfile lacks: " + target_section_name)
s.st_shndx = objfile_section.index
# glabel's aren't marked as functions, making objdump output confusing. Fix that.
if s.name in all_text_glabels:
s.type = STT_FUNC
if s.name in func_sizes:
s.st_size = func_sizes[s.name]
if objfile.sections[s.st_shndx].name == '.rodata' and s.st_value in moved_late_rodata:
if section_name == '.late_rodata':
if s.st_value == 0:
# This must be a symbol corresponding to the whole .late_rodata
# section, being referred to from a relocation.
# Moving local symbols is tricky, because it requires fixing up
# lo16/hi16 relocation references to .late_rodata+<offset>.
# Just disallow it for now.
raise Failure("local symbols in .late_rodata are not allowed")
s.st_value = moved_late_rodata[s.st_value]
s.st_name += strtab_adj
if is_local:
new_local_syms.append(s)
else:
new_global_syms.append(s)
new_syms.append(s)
make_statics_global = convert_statics in ("global", "global-with-filename")
# Add static symbols from .mdebug, so they can be referred to from GLOBAL_ASM
local_sym_replacements = {}
if mdebug_section:
if mdebug_section and convert_statics != "no":
strtab_index = len(objfile.symtab.strtab.data)
new_strtab_data = []
ifd_max, cb_fd_offset = struct.unpack('>II', mdebug_section.data[18*4 : 20*4])
cb_sym_offset, = struct.unpack('>I', mdebug_section.data[9*4 : 10*4])
cb_ss_offset, = struct.unpack('>I', mdebug_section.data[15*4 : 16*4])
ifd_max, cb_fd_offset = fmt.unpack('II', mdebug_section.data[18*4 : 20*4])
cb_sym_offset, = fmt.unpack('I', mdebug_section.data[9*4 : 10*4])
cb_ss_offset, = fmt.unpack('I', mdebug_section.data[15*4 : 16*4])
for i in range(ifd_max):
offset = cb_fd_offset + 18*4*i
iss_base, _, isym_base, csym = struct.unpack('>IIII', objfile.data[offset + 2*4 : offset + 6*4])
iss_base, _, isym_base, csym = fmt.unpack('IIII', objfile.data[offset + 2*4 : offset + 6*4])
for j in range(csym):
offset2 = cb_sym_offset + 12 * (isym_base + j)
iss, value, st_sc_index = struct.unpack('>III', objfile.data[offset2 : offset2 + 12])
iss, value, st_sc_index = fmt.unpack('III', objfile.data[offset2 : offset2 + 12])
st = (st_sc_index >> 26)
sc = (st_sc_index >> 21) & 0x1f
if st in [MIPS_DEBUG_ST_STATIC, MIPS_DEBUG_ST_STATIC_PROC]:
@ -1157,44 +1286,72 @@ def fixup_objfile(objfile_name, functions, asm_prelude, assembler, output_enc, d
symbol_name_offset_end = objfile.data.find(b'\0', symbol_name_offset)
assert symbol_name_offset_end != -1
symbol_name = objfile.data[symbol_name_offset : symbol_name_offset_end + 1]
symbol_name_str = symbol_name[:-1].decode('latin1')
emitted_symbol_name = symbol_name
if convert_statics == "global-with-filename":
# Change the emitted symbol name to include the filename,
# but don't let that affect deduplication logic.
emitted_symbol_name = objfile_name.encode("utf-8") + b":" + symbol_name
section_name = {1: '.text', 2: '.data', 3: '.bss', 15: '.rodata'}[sc]
section = objfile.find_section(section_name)
symtype = STT_FUNC if sc == 1 else STT_OBJECT
binding = STB_GLOBAL if make_statics_global else STB_LOCAL
sym = Symbol.from_parts(
fmt,
st_name=strtab_index,
st_value=value,
st_size=0,
st_info=(STB_LOCAL << 4 | symtype),
st_info=(binding << 4 | symtype),
st_other=STV_DEFAULT,
st_shndx=section.index,
strtab=objfile.symtab.strtab,
name=symbol_name_str)
local_sym_replacements[symbol_name_str] = len(new_local_syms)
strtab_index += len(symbol_name)
new_strtab_data.append(symbol_name)
new_local_syms.append(sym)
name=symbol_name[:-1].decode('latin1'))
strtab_index += len(emitted_symbol_name)
new_strtab_data.append(emitted_symbol_name)
new_syms.append(sym)
objfile.symtab.strtab.data += b''.join(new_strtab_data)
# To get the linker to use the local symbols, we have to get rid of UNDEF
# global ones.
newer_global_syms = []
for s in new_global_syms:
if s.st_shndx == SHN_UNDEF and s.name in local_sym_replacements:
s.new_index = local_sym_replacements[s.name]
# Get rid of duplicate symbols, favoring ones that are not UNDEF.
# Skip this for unnamed local symbols though.
new_syms.sort(key=lambda s: 0 if s.st_shndx != SHN_UNDEF else 1)
old_syms = []
newer_syms = []
name_to_sym = {}
for s in new_syms:
if s.name == "_gp_disp":
s.type = STT_OBJECT
if s.bind == STB_LOCAL and s.st_shndx == SHN_UNDEF:
raise Failure("local symbol \"" + s.name + "\" is undefined")
if not s.name:
if s.bind != STB_LOCAL:
raise Failure("global symbol with no name")
newer_syms.append(s)
else:
newer_global_syms.append(s)
new_global_syms = newer_global_syms
existing = name_to_sym.get(s.name)
if not existing:
name_to_sym[s.name] = s
newer_syms.append(s)
elif s.st_shndx != SHN_UNDEF:
raise Failure("symbol \"" + s.name + "\" defined twice")
else:
s.replace_by = existing
old_syms.append(s)
new_syms = newer_syms
# Put local symbols in front, with the initial dummy entry first, and
# _gp_disp at the end if it exists.
new_syms.insert(0, empty_symbol)
new_syms.sort(key=lambda s: (s.bind != STB_LOCAL, s.name == "_gp_disp"))
num_local_syms = sum(1 for s in new_syms if s.bind == STB_LOCAL)
new_syms = new_local_syms + new_global_syms
for i, s in enumerate(new_syms):
s.new_index = i
for s in old_syms:
s.new_index = s.replace_by.new_index
objfile.symtab.data = b''.join(s.to_bin() for s in new_syms)
objfile.symtab.sh_info = len(new_local_syms)
objfile.symtab.sh_info = num_local_syms
# Move over relocations
# Fix up relocation symbol references
for sectype in SECTIONS:
source = asm_objfile.find_section(sectype)
target = objfile.find_section(sectype)
if target is not None:
@ -1206,34 +1363,38 @@ def fixup_objfile(objfile_name, functions, asm_prelude, assembler, output_enc, d
sectype == '.rodata' and rel.r_offset in jtbl_rodata_positions):
# don't include relocations for late_rodata dummy code
continue
# hopefully we don't have relocations for local or
# temporary symbols, so new_index exists
rel.sym_index = objfile.symtab.symbol_entries[rel.sym_index].new_index
nrels.append(rel)
reltab.relocations = nrels
reltab.data = b''.join(rel.to_bin() for rel in nrels)
if not source:
# Move over relocations
for sectype in SECTIONS + ['.late_rodata']:
source = asm_objfile.find_section(sectype)
if source is None or not source.data:
continue
target_reltab = objfile.find_section('.rel' + sectype)
target_reltaba = objfile.find_section('.rela' + sectype)
target_sectype = '.rodata' if sectype == '.late_rodata' else sectype
target = objfile.find_section(target_sectype)
assert target is not None, target_sectype
target_reltab = objfile.find_section('.rel' + target_sectype)
target_reltaba = objfile.find_section('.rela' + target_sectype)
for reltab in source.relocated_by:
for rel in reltab.relocations:
rel.sym_index = asm_objfile.symtab.symbol_entries[rel.sym_index].new_index
if sectype == '.rodata' and rel.r_offset in moved_late_rodata:
if sectype == '.late_rodata':
rel.r_offset = moved_late_rodata[rel.r_offset]
new_data = b''.join(rel.to_bin() for rel in reltab.relocations)
if reltab.sh_type == SHT_REL:
if not target_reltab:
target_reltab = objfile.add_section('.rel' + sectype,
target_reltab = objfile.add_section('.rel' + target_sectype,
sh_type=SHT_REL, sh_flags=0,
sh_link=objfile.symtab.index, sh_info=target.index,
sh_addralign=4, sh_entsize=8, data=b'')
target_reltab.data += new_data
else:
if not target_reltaba:
target_reltaba = objfile.add_section('.rela' + sectype,
target_reltaba = objfile.add_section('.rela' + target_sectype,
sh_type=SHT_RELA, sh_flags=0,
sh_link=objfile.symtab.index, sh_info=target.index,
sh_addralign=4, sh_entsize=12, data=b'')
@ -1257,9 +1418,12 @@ def run_wrapped(argv, outfile, functions):
parser.add_argument('--input-enc', default='latin1', help="input encoding (default: %(default)s)")
parser.add_argument('--output-enc', default='latin1', help="output encoding (default: %(default)s)")
parser.add_argument('--drop-mdebug-gptab', dest='drop_mdebug_gptab', action='store_true', help="drop mdebug and gptab sections")
parser.add_argument('--convert-statics', dest='convert_statics', choices=["no", "local", "global", "global-with-filename"], default="local", help="change static symbol visibility (default: %(default)s)")
parser.add_argument('--force', dest='force', action='store_true', help="force processing of files without GLOBAL_ASM blocks")
parser.add_argument('-framepointer', dest='framepointer', action='store_true')
parser.add_argument('-mips1', dest='mips1', action='store_true')
parser.add_argument('-g3', dest='g3', action='store_true')
parser.add_argument('-KPIC', dest='kpic', action='store_true')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-O0', dest='opt', action='store_const', const='O0')
group.add_argument('-O1', dest='opt', action='store_const', const='O1')
@ -1267,31 +1431,35 @@ def run_wrapped(argv, outfile, functions):
group.add_argument('-g', dest='opt', action='store_const', const='g')
args = parser.parse_args(argv)
opt = args.opt
pascal = any(args.filename.endswith(ext) for ext in (".p", ".pas", ".pp"))
if args.g3:
if opt != 'O2':
raise Failure("-g3 is only supported together with -O2")
opt = 'g3'
if args.mips1 and (opt != 'O2' or args.framepointer):
raise Failure("-mips1 is only supported together with -O2")
if args.mips1 and (opt not in ('O1', 'O2') or args.framepointer):
raise Failure("-mips1 is only supported together with -O1 or -O2")
if pascal and opt not in ('O1', 'O2', 'g3'):
raise Failure("Pascal is only supported together with -O1, -O2 or -O2 -g3")
opts = Opts(opt, args.framepointer, args.mips1, args.kpic, pascal, args.input_enc, args.output_enc)
if args.objfile is None:
with open(args.filename, encoding=args.input_enc) as f:
deps = []
functions = parse_source(f, opt=opt, framepointer=args.framepointer, mips1=args.mips1, input_enc=args.input_enc, output_enc=args.output_enc, out_dependencies=deps, print_source=outfile)
functions = parse_source(f, opts, out_dependencies=deps, print_source=outfile)
return functions, deps
else:
if args.assembler is None:
raise Failure("must pass assembler command")
if functions is None:
with open(args.filename, encoding=args.input_enc) as f:
functions = parse_source(f, opt=opt, framepointer=args.framepointer, mips1=args.mips1, input_enc=args.input_enc, out_dependencies=[], output_enc=args.output_enc)
if not functions:
functions = parse_source(f, opts, out_dependencies=[])
if not functions and not args.force:
return
asm_prelude = b''
if args.asm_prelude:
with open(args.asm_prelude, 'rb') as f:
asm_prelude = f.read()
fixup_objfile(args.objfile, functions, asm_prelude, args.assembler, args.output_enc, args.drop_mdebug_gptab)
fixup_objfile(args.objfile, functions, asm_prelude, args.assembler, args.output_enc, args.drop_mdebug_gptab, args.convert_statics)
def run(argv, outfile=sys.stdout.buffer, functions=None):
try:

78
tools/asm-processor/build.py Executable file → Normal file
View File

@ -1,41 +1,50 @@
#!/usr/bin/env python3
import sys
import os
from pathlib import Path
import shlex
import subprocess
import tempfile
import uuid
import asm_processor
dir_path = os.path.dirname(os.path.realpath(__file__))
prelude = os.path.join(dir_path, "prelude.inc")
# Boolean for debugging purposes
# Preprocessed files are temporary, set to True to keep a copy
keep_preprocessed_files = False
dir_path = Path(__file__).resolve().parent
asm_prelude_path = dir_path / "prelude.inc"
all_args = sys.argv[1:]
sep0 = [index for index, arg in enumerate(all_args) if not arg.startswith("-")][0]
sep0 = next(index for index, arg in enumerate(all_args) if not arg.startswith("-"))
sep1 = all_args.index("--")
sep2 = all_args.index("--", sep1 + 1)
asmproc_flags = all_args[:sep0]
compiler = all_args[sep0:sep1]
assembler = all_args[sep1 + 1 : sep2]
assembler_sh = " ".join(shlex.quote(x) for x in assembler)
assembler_args = all_args[sep1 + 1 : sep2]
assembler_sh = " ".join(shlex.quote(x) for x in assembler_args)
compile_args = all_args[sep2 + 1 :]
in_file = compile_args[-1]
out_ind = compile_args.index("-o")
out_file = compile_args[out_ind + 1]
in_file = Path(compile_args[-1])
del compile_args[-1]
out_ind = compile_args.index("-o")
out_file = Path(compile_args[out_ind + 1])
del compile_args[out_ind + 1]
del compile_args[out_ind]
in_dir = os.path.split(os.path.realpath(in_file))[0]
in_dir = in_file.resolve().parent
opt_flags = [
x for x in compile_args if x in ["-g3", "-g", "-O0", "-O1", "-O2", "-framepointer"]
x for x in compile_args if x in {"-g3", "-g", "-O0", "-O1", "-O2", "-framepointer", "-KPIC"}
]
if "-mips2" not in compile_args:
opt_flags.append("-mips1")
asmproc_flags += opt_flags + [in_file]
asmproc_flags += opt_flags + [str(in_file)]
# Drop .mdebug and .gptab sections from resulting binaries. This makes
# resulting .o files much smaller and speeds up builds, but loses line
@ -45,50 +54,61 @@ asmproc_flags += opt_flags + [in_file]
# Convert encoding before compiling.
# asmproc_flags += ["--input-enc", "utf-8", "--output-enc", "euc-jp"]
preprocessed_file = tempfile.NamedTemporaryFile(
prefix="preprocessed", suffix=".c", delete=False
)
with tempfile.TemporaryDirectory(prefix="asm_processor") as tmpdirname:
tmpdir_path = Path(tmpdirname)
preprocessed_filename = "preprocessed_" + uuid.uuid4().hex + in_file.suffix
preprocessed_path = tmpdir_path / preprocessed_filename
with preprocessed_path.open("wb") as f:
functions, deps = asm_processor.run(asmproc_flags, outfile=f)
if keep_preprocessed_files:
import shutil
keep_output_dir = Path("./asm_processor_preprocessed")
keep_output_dir.mkdir(parents=True, exist_ok=True)
shutil.copy(
preprocessed_path,
keep_output_dir / (in_file.stem + "_" + preprocessed_filename),
)
try:
compile_cmdline = (
compiler + compile_args + ["-I", in_dir, "-o", out_file, preprocessed_file.name]
compiler
+ compile_args
+ ["-I", str(in_dir), "-o", str(out_file), str(preprocessed_path)]
)
functions, deps = asm_processor.run(asmproc_flags, outfile=preprocessed_file)
try:
subprocess.check_call(compile_cmdline)
except subprocess.CalledProcessError as e:
print("Failed to compile file " + in_file + ". Command line:")
print("Failed to compile file " + str(in_file) + ". Command line:")
print()
print(" ".join(shlex.quote(x) for x in compile_cmdline))
print()
sys.exit(55)
# To keep the preprocessed file:
# os._exit(1)
asm_processor.run(
asmproc_flags
+ [
"--post-process",
out_file,
str(out_file),
"--assembler",
assembler_sh,
"--asm-prelude",
prelude,
str(asm_prelude_path),
],
functions=functions,
)
deps_file = out_file[:-2] + ".asmproc.d"
deps_file = out_file.with_suffix(".asmproc.d")
if deps:
with open(deps_file, "w") as f:
f.write(out_file + ": " + " \\\n ".join(deps) + "\n")
with deps_file.open("w") as f:
f.write(str(out_file) + ": " + " \\\n ".join(deps) + "\n")
for dep in deps:
f.write("\n" + dep + ":\n")
else:
try:
os.remove(deps_file)
deps_file.unlink()
except OSError:
pass
finally:
os.remove(preprocessed_file.name)

View File

@ -0,0 +1,26 @@
#!/bin/bash
set -o pipefail
INPUT="$1"
OUTPUT="${INPUT%.*}.o"
rm -f "$OUTPUT"
CC="$MIPS_CC" # ido 7.1 via recomp or qemu-irix
AS="mips-linux-gnu-as"
ASFLAGS="-march=vr4300 -mabi=32"
OPTFLAGS=$(grep 'COMPILE-FLAGS: ' $INPUT | sed 's#^.*COMPILE-FLAGS: ##' | sed 's#}$##')
ASMPFLAGS=$(grep 'ASMP-FLAGS: ' $INPUT | sed 's#^.*ASMP-FLAGS: ##' | sed 's#}$##')
ISET=$(grep 'COMPILE-ISET: ' $INPUT | sed 's#^.*COMPILE-ISET: ##' | sed 's#}$##')
if [[ -z "$OPTFLAGS" ]]; then
OPTFLAGS="-g"
fi
CFLAGS="-Wab,-r4300_mul -G 0 -Xcpluscomm -fullwarn -wlint -woff 819,820,852,821 -signed -c"
if [[ -z "$ISET" ]]; then
CFLAGS="$CFLAGS -mips2"
fi
if [[ "$OPTFLAGS" != *-KPIC* ]]; then
CFLAGS="$CFLAGS -non_shared"
fi
set -e
python3 build.py --drop-mdebug-gptab $ASMPFLAGS $CC -- $AS $ASFLAGS -- $CFLAGS $OPTFLAGS $ISET -o "$OUTPUT" "$INPUT"

View File

@ -0,0 +1,6 @@
#!/usr/bin/env bash
for A in tests/*.c tests/*.p; do
OBJDUMPFLAGS=-srt
echo $A
./compile-test.sh "$A" && mips-linux-gnu-objdump $OBJDUMPFLAGS "${A%.*}.o" | diff - "${A%.*}.objdump" || echo FAIL "$A"
done

View File

@ -0,0 +1,19 @@
void foo(void) { "abcdef"; }
GLOBAL_ASM(
.rdata
.ascii "AB"
.ascii "CD", "EF"
.ascii "GH\n\n\n\0\11\222\3333\44444\x1234567\n\nIJK"
)
void bar(void) { "hello"; }
GLOBAL_ASM(
.rdata
.asciiz "12"
.asciiz "34", "56"
.asciiz "78\n\n\n\0\11\222\3333\44444\x1234567\n\n9A"
)
void baz(void) { "ghijkl"; }

View File

@ -0,0 +1,29 @@
tests/ascii.o: file format elf32-tradbigmips
SYMBOL TABLE:
00000000 l d .text 00000030 .text
00000000 l d .rodata 00000050 .rodata
00000000 g F .text 00000010 foo
00000010 g F .text 00000010 bar
00000020 g F .text 00000010 baz
Contents of section .text:
0000 03e00008 00000000 03e00008 00000000 ................
0010 03e00008 00000000 03e00008 00000000 ................
0020 03e00008 00000000 03e00008 00000000 ................
Contents of section .rodata:
0000 61626364 65660000 41424344 45464748 abcdef..ABCDEFGH
0010 0a0a0a00 0992db33 24343467 0a0a494a .......3$44g..IJ
0020 4b000000 68656c6c 6f000000 31320033 K...hello...12.3
0030 34003536 0037380a 0a0a0009 92db3324 4.56.78.......3$
0040 3434670a 0a394100 6768696a 6b6c0000 44g..9A.ghijkl..
Contents of section .options:
0000 01200000 00000000 80000000 00000000 . ..............
0010 00000000 00000000 00000000 00007ff0 ................
0020 07100000 00000000 00000000 00000000 ................
0030 08100000 00000000 00000000 00000000 ................
Contents of section .reginfo:
0000 80000000 00000000 00000000 00000000 ................
0010 00000000 00007ff0 ........

View File

@ -0,0 +1,6 @@
const char before[] = "^";
GLOBAL_ASM(
.rdata
.asciz "aaaa /* bbbb */ # cccc", /**//**//**//**/ /*/ "xxxx" /*/ /* dddd " eeee */ "# ffff" # gggg "hhhh" /* iiii */
)
const char after[] = "$";

View File

@ -0,0 +1,21 @@
tests/comments.o: file format elf32-tradbigmips
SYMBOL TABLE:
00000000 l d .rodata 00000030 .rodata
00000000 g O .rodata 00000002 before
00000024 g O .rodata 00000002 after
Contents of section .rodata:
0000 5e000000 61616161 202f2a20 62626262 ^...aaaa /* bbbb
0010 202a2f20 23206363 63630023 20666666 */ # cccc.# fff
0020 66000000 24000000 00000000 00000000 f...$...........
Contents of section .options:
0000 01200000 00000000 00000000 00000000 . ..............
0010 00000000 00000000 00000000 00007ff0 ................
0020 07100000 00000000 00000000 00000000 ................
0030 08100000 00000000 00000000 00000000 ................
Contents of section .reginfo:
0000 00000000 00000000 00000000 00000000 ................
0010 00000000 00007ff0 ........

View File

@ -0,0 +1,17 @@
// COMPILE-FLAGS: -O2
// ASMP-FLAGS: --convert-statics=global-with-filename --force
static int xtext(int a, int b, int c);
const int rodata1[] = {1};
static const int rodata2[] = {2};
int data1[] = {3};
static int data2[] = {4};
int bss1;
static int bss2;
static int xtext(int a, int b, int c) {
return 1;
}
void baz(void) {
xtext(bss2, rodata2[0], data2[0]);
}

View File

@ -0,0 +1,47 @@
tests/force.o: file format elf32-tradbigmips
SYMBOL TABLE:
00000000 l d .text 00000050 .text
00000000 l d .rodata 00000010 .rodata
00000000 l d .data 00000010 .data
00000000 l d .bss 00000010 .bss
00000000 g O .rodata 00000004 rodata1
00000000 g O .data 00000004 data1
00000000 g O .bss 00000004 bss1
00000014 g F .text 00000034 baz
00000004 g O .rodata 00000000 tests/force.o:rodata2
00000004 g O .data 00000000 tests/force.o:data2
00000004 g O .bss 00000000 tests/force.o:bss2
00000000 g F .text 00000000 tests/force.o:xtext
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
0000001c R_MIPS_HI16 .bss
00000034 R_MIPS_LO16 .bss
00000020 R_MIPS_HI16 .rodata
0000002c R_MIPS_LO16 .rodata
00000024 R_MIPS_HI16 .data
00000028 R_MIPS_LO16 .data
00000030 R_MIPS_26 .text
Contents of section .text:
0000 afa40000 afa50004 afa60008 03e00008 ................
0010 24020001 27bdffe8 afbf0014 3c040000 $...'.......<...
0020 3c050000 3c060000 8cc60004 8ca50004 <...<...........
0030 0c000000 8c840004 8fbf0014 27bd0018 ............'...
0040 03e00008 00000000 00000000 00000000 ................
Contents of section .rodata:
0000 00000001 00000002 00000000 00000000 ................
Contents of section .data:
0000 00000003 00000004 00000000 00000000 ................
Contents of section .options:
0000 01200000 00000000 a0000074 00000000 . .........t....
0010 00000000 00000000 00000000 00007ff0 ................
0020 07100000 00000000 00000000 00000000 ................
0030 08100000 00000000 00000000 00000000 ................
Contents of section .reginfo:
0000 a0000074 00000000 00000000 00000000 ...t............
0010 00000000 00007ff0 ........

View File

@ -0,0 +1,93 @@
// COMPILE-FLAGS: -O1 -KPIC
GLOBAL_ASM(
glabel foo
addiu $a0, $a0, 1
addiu $a0, $a0, 2
addiu $a0, $a0, 3
addiu $a0, $a0, 4
addiu $a0, $a0, 5
addiu $a0, $a0, 6
addiu $a0, $a0, 7
addiu $a0, $a0, 8
addiu $a0, $a0, 9
addiu $a0, $a0, 10
addiu $a0, $a0, 11
addiu $a0, $a0, 12
)
GLOBAL_ASM(
.late_rodata
.float 1
.text
glabel float_fn
addiu $a0, $a0, 13
addiu $a0, $a0, 14
addiu $a0, $a0, 15
addiu $a0, $a0, 16
addiu $a0, $a0, 17
addiu $a0, $a0, 18
addiu $a0, $a0, 19
addiu $a0, $a0, 20
addiu $a0, $a0, 21
addiu $a0, $a0, 22
addiu $a0, $a0, 23
addiu $a0, $a0, 24
addiu $a0, $a0, 25
addiu $a0, $a0, 26
addiu $a0, $a0, 27
addiu $a0, $a0, 28
addiu $a0, $a0, 29
addiu $a0, $a0, 30
)
GLOBAL_ASM(
.late_rodata
.late_rodata_alignment 4
.float 2
.double 1
.double 2
.double 3
.double 4
.double 5
.double 6
.double 7
.double 8
.text
glabel doubles
addiu $a0, $a0, 31
addiu $a0, $a0, 32
addiu $a0, $a0, 33
addiu $a0, $a0, 34
addiu $a0, $a0, 35
addiu $a0, $a0, 36
addiu $a0, $a0, 37
addiu $a0, $a0, 38
addiu $a0, $a0, 39
addiu $a0, $a0, 40
addiu $a0, $a0, 41
addiu $a0, $a0, 42
addiu $a0, $a0, 43
addiu $a0, $a0, 44
addiu $a0, $a0, 45
addiu $a0, $a0, 46
addiu $a0, $a0, 47
addiu $a0, $a0, 48
addiu $a0, $a0, 49
addiu $a0, $a0, 50
addiu $a0, $a0, 51
addiu $a0, $a0, 52
addiu $a0, $a0, 53
addiu $a0, $a0, 54
addiu $a0, $a0, 55
addiu $a0, $a0, 56
addiu $a0, $a0, 57
addiu $a0, $a0, 58
addiu $a0, $a0, 59
addiu $a0, $a0, 60
addiu $a0, $a0, 61
addiu $a0, $a0, 62
addiu $a0, $a0, 63
addiu $a0, $a0, 64
addiu $a0, $a0, 65
addiu $a0, $a0, 66
addiu $a0, $a0, 67
addiu $a0, $a0, 68
)

View File

@ -0,0 +1,46 @@
tests/kpic-o1.o: file format elf32-tradbigmips
SYMBOL TABLE:
00000000 l d .text 00000110 .text
00000000 l d .rodata 00000050 .rodata
00000000 g F .text 00000030 foo
00000030 g F .text 00000048 float_fn
00000078 g F .text 00000098 doubles
00000000 O *UND* 00000000 _gp_disp
RELOCATION RECORDS FOR [.text]: (none)
Contents of section .text:
0000 24840001 24840002 24840003 24840004 $...$...$...$...
0010 24840005 24840006 24840007 24840008 $...$...$...$...
0020 24840009 2484000a 2484000b 2484000c $...$...$...$...
0030 2484000d 2484000e 2484000f 24840010 $...$...$...$...
0040 24840011 24840012 24840013 24840014 $...$...$...$...
0050 24840015 24840016 24840017 24840018 $...$...$...$...
0060 24840019 2484001a 2484001b 2484001c $...$...$...$...
0070 2484001d 2484001e 2484001f 24840020 $...$...$...$..
0080 24840021 24840022 24840023 24840024 $..!$.."$..#$..$
0090 24840025 24840026 24840027 24840028 $..%$..&$..'$..(
00a0 24840029 2484002a 2484002b 2484002c $..)$..*$..+$..,
00b0 2484002d 2484002e 2484002f 24840030 $..-$...$../$..0
00c0 24840031 24840032 24840033 24840034 $..1$..2$..3$..4
00d0 24840035 24840036 24840037 24840038 $..5$..6$..7$..8
00e0 24840039 2484003a 2484003b 2484003c $..9$..:$..;$..<
00f0 2484003d 2484003e 2484003f 24840040 $..=$..>$..?$..@
0100 24840041 24840042 24840043 24840044 $..A$..B$..C$..D
Contents of section .rodata:
0000 3f800000 40000000 3ff00000 00000000 ?...@...?.......
0010 40000000 00000000 40080000 00000000 @.......@.......
0020 40100000 00000000 40140000 00000000 @.......@.......
0030 40180000 00000000 401c0000 00000000 @.......@.......
0040 40200000 00000000 00000000 00000000 @ ..............
Contents of section .options:
0000 01200000 00000000 92000002 00000000 . ..............
0010 000f0ff0 00000000 00000000 00000000 ................
0020 07100000 00000000 00000000 00000000 ................
0030 08100000 00000000 00000000 00000000 ................
Contents of section .reginfo:
0000 92000012 00000000 000f0ff0 00000000 ................
0010 00000000 00000000 ........

View File

@ -0,0 +1,92 @@
// COMPILE-FLAGS: -O2 -KPIC
GLOBAL_ASM(
glabel foo
addiu $a0, $a0, 1
addiu $a0, $a0, 2
addiu $a0, $a0, 3
addiu $a0, $a0, 4
addiu $a0, $a0, 5
addiu $a0, $a0, 6
addiu $a0, $a0, 7
addiu $a0, $a0, 8
addiu $a0, $a0, 9
addiu $a0, $a0, 10
addiu $a0, $a0, 11
addiu $a0, $a0, 12
)
GLOBAL_ASM(
.late_rodata
.float 1
.text
glabel float_fn
addiu $a0, $a0, 13
addiu $a0, $a0, 14
addiu $a0, $a0, 15
addiu $a0, $a0, 16
addiu $a0, $a0, 17
addiu $a0, $a0, 18
addiu $a0, $a0, 19
addiu $a0, $a0, 20
addiu $a0, $a0, 21
addiu $a0, $a0, 22
addiu $a0, $a0, 23
addiu $a0, $a0, 24
addiu $a0, $a0, 25
addiu $a0, $a0, 26
addiu $a0, $a0, 27
addiu $a0, $a0, 28
addiu $a0, $a0, 29
addiu $a0, $a0, 30
)
GLOBAL_ASM(
.late_rodata
.float 2
.double 1
.double 2
.double 3
.double 4
.double 5
.double 6
.double 7
.double 8
.text
glabel doubles
addiu $a0, $a0, 31
addiu $a0, $a0, 32
addiu $a0, $a0, 33
addiu $a0, $a0, 34
addiu $a0, $a0, 35
addiu $a0, $a0, 36
addiu $a0, $a0, 37
addiu $a0, $a0, 38
addiu $a0, $a0, 39
addiu $a0, $a0, 40
addiu $a0, $a0, 41
addiu $a0, $a0, 42
addiu $a0, $a0, 43
addiu $a0, $a0, 44
addiu $a0, $a0, 45
addiu $a0, $a0, 46
addiu $a0, $a0, 47
addiu $a0, $a0, 48
addiu $a0, $a0, 49
addiu $a0, $a0, 50
addiu $a0, $a0, 51
addiu $a0, $a0, 52
addiu $a0, $a0, 53
addiu $a0, $a0, 54
addiu $a0, $a0, 55
addiu $a0, $a0, 56
addiu $a0, $a0, 57
addiu $a0, $a0, 58
addiu $a0, $a0, 59
addiu $a0, $a0, 60
addiu $a0, $a0, 61
addiu $a0, $a0, 62
addiu $a0, $a0, 63
addiu $a0, $a0, 64
addiu $a0, $a0, 65
addiu $a0, $a0, 66
addiu $a0, $a0, 67
addiu $a0, $a0, 68
)

View File

@ -0,0 +1,46 @@
tests/kpic-o2.o: file format elf32-tradbigmips
SYMBOL TABLE:
00000000 l d .text 00000110 .text
00000000 l d .rodata 00000050 .rodata
00000000 g F .text 00000030 foo
00000030 g F .text 00000048 float_fn
00000078 g F .text 00000098 doubles
00000000 O *UND* 00000000 _gp_disp
RELOCATION RECORDS FOR [.text]: (none)
Contents of section .text:
0000 24840001 24840002 24840003 24840004 $...$...$...$...
0010 24840005 24840006 24840007 24840008 $...$...$...$...
0020 24840009 2484000a 2484000b 2484000c $...$...$...$...
0030 2484000d 2484000e 2484000f 24840010 $...$...$...$...
0040 24840011 24840012 24840013 24840014 $...$...$...$...
0050 24840015 24840016 24840017 24840018 $...$...$...$...
0060 24840019 2484001a 2484001b 2484001c $...$...$...$...
0070 2484001d 2484001e 2484001f 24840020 $...$...$...$..
0080 24840021 24840022 24840023 24840024 $..!$.."$..#$..$
0090 24840025 24840026 24840027 24840028 $..%$..&$..'$..(
00a0 24840029 2484002a 2484002b 2484002c $..)$..*$..+$..,
00b0 2484002d 2484002e 2484002f 24840030 $..-$...$../$..0
00c0 24840031 24840032 24840033 24840034 $..1$..2$..3$..4
00d0 24840035 24840036 24840037 24840038 $..5$..6$..7$..8
00e0 24840039 2484003a 2484003b 2484003c $..9$..:$..;$..<
00f0 2484003d 2484003e 2484003f 24840040 $..=$..>$..?$..@
0100 24840041 24840042 24840043 24840044 $..A$..B$..C$..D
Contents of section .rodata:
0000 3f800000 40000000 3ff00000 00000000 ?...@...?.......
0010 40000000 00000000 40080000 00000000 @.......@.......
0020 40100000 00000000 40140000 00000000 @.......@.......
0030 40180000 00000000 401c0000 00000000 @.......@.......
0040 40200000 00000000 00000000 00000000 @ ..............
Contents of section .options:
0000 01200000 00000000 92000002 00000000 . ..............
0010 000f0ff0 00000000 00000000 00000000 ................
0020 07100000 00000000 00000000 00000000 ................
0030 08100000 00000000 00000000 00000000 ................
Contents of section .reginfo:
0000 92000012 00000000 000f0ff0 00000000 ................
0010 00000000 00000000 ........

View File

@ -0,0 +1,7 @@
GLOBAL_ASM(
.rdata
.word 0x12345678
glabel blah
.word blah2
/*a*/ blah2: /*b*/ .word blah /*c*/
)

View File

@ -0,0 +1,25 @@
tests/label-sameline.o: file format elf32-tradbigmips
SYMBOL TABLE:
00000000 l d .rodata 00000010 .rodata
00000000 l d .rodata 00000000
00000004 g .rodata 00000000 blah
RELOCATION RECORDS FOR [.rodata]:
OFFSET TYPE VALUE
00000004 R_MIPS_32
00000008 R_MIPS_32 blah
Contents of section .rodata:
0000 12345678 00000008 00000000 00000000 .4Vx............
Contents of section .options:
0000 01200000 00000000 00000000 00000000 . ..............
0010 00000000 00000000 00000000 00007ff0 ................
0020 07100000 00000000 00000000 00000000 ................
0030 08100000 00000000 00000000 00000000 ................
Contents of section .reginfo:
0000 00000000 00000000 00000000 00000000 ................
0010 00000000 00007ff0 ........

View File

@ -0,0 +1,164 @@
GLOBAL_ASM(
glabel test
addiu $sp, $sp, -24
sw $zero, 4($sp)
lw $t6, 4($sp)
addu $t7, $a0, $t6
sb $zero, ($t7)
lw $t8, 4($sp)
addiu $t9, $t8, 1
slt $at, $t9, $a1
sw $t9, 4($sp)
nop
jr $ra
addiu $sp, $sp, 24
addiu $sp, $sp, -24
sw $zero, 4($sp)
lw $t6, 4($sp)
addu $t7, $a0, $t6
sb $zero, ($t7)
lw $t8, 4($sp)
addiu $t9, $t8, 1
slt $at, $t9, $a1
sw $t9, 4($sp)
nop
jr $ra
addiu $sp, $sp, 24
addiu $sp, $sp, -24
sw $zero, 4($sp)
lw $t6, 4($sp)
addu $t7, $a0, $t6
sb $zero, ($t7)
lw $t8, 4($sp)
addiu $t9, $t8, 1
slt $at, $t9, $a1
sw $t9, 4($sp)
nop
jr $ra
addiu $sp, $sp, 24
addiu $sp, $sp, -24
sw $zero, 4($sp)
lw $t6, 4($sp)
addu $t7, $a0, $t6
sb $zero, ($t7)
lw $t8, 4($sp)
addiu $t9, $t8, 1
slt $at, $t9, $a1
sw $t9, 4($sp)
nop
jr $ra
addiu $sp, $sp, 24
addiu $sp, $sp, -24
sw $zero, 4($sp)
lw $t6, 4($sp)
addu $t7, $a0, $t6
sb $zero, ($t7)
lw $t8, 4($sp)
addiu $t9, $t8, 1
slt $at, $t9, $a1
sw $t9, 4($sp)
nop
jr $ra
addiu $sp, $sp, 24
addiu $sp, $sp, -24
sw $zero, 4($sp)
lw $t6, 4($sp)
addu $t7, $a0, $t6
sb $zero, ($t7)
lw $t8, 4($sp)
addiu $t9, $t8, 1
slt $at, $t9, $a1
sw $t9, 4($sp)
nop
jr $ra
addiu $sp, $sp, 24
addiu $sp, $sp, -24
sw $zero, 4($sp)
lw $t6, 4($sp)
addu $t7, $a0, $t6
sb $zero, ($t7)
lw $t8, 4($sp)
addiu $t9, $t8, 1
slt $at, $t9, $a1
sw $t9, 4($sp)
nop
jr $ra
addiu $sp, $sp, 24
addiu $sp, $sp, -24
sw $zero, 4($sp)
lw $t6, 4($sp)
addu $t7, $a0, $t6
sb $zero, ($t7)
lw $t8, 4($sp)
addiu $t9, $t8, 1
slt $at, $t9, $a1
sw $t9, 4($sp)
nop
jr $ra
addiu $sp, $sp, 24
addiu $sp, $sp, -24
sw $zero, 4($sp)
lw $t6, 4($sp)
addu $t7, $a0, $t6
sb $zero, ($t7)
lw $t8, 4($sp)
addiu $t9, $t8, 1
slt $at, $t9, $a1
sw $t9, 4($sp)
nop
jr $ra
addiu $sp, $sp, 24
addiu $sp, $sp, -24
sw $zero, 4($sp)
lw $t6, 4($sp)
addu $t7, $a0, $t6
sb $zero, ($t7)
lw $t8, 4($sp)
addiu $t9, $t8, 1
slt $at, $t9, $a1
sw $t9, 4($sp)
nop
jr $ra
addiu $sp, $sp, 24
addiu $sp, $sp, -24
sw $zero, 4($sp)
lw $t6, 4($sp)
addu $t7, $a0, $t6
sb $zero, ($t7)
lw $t8, 4($sp)
addiu $t9, $t8, 1
slt $at, $t9, $a1
sw $t9, 4($sp)
nop
jr $ra
addiu $sp, $sp, 24
addiu $sp, $sp, -24
sw $zero, 4($sp)
lw $t6, 4($sp)
addu $t7, $a0, $t6
sb $zero, ($t7)
lw $t8, 4($sp)
addiu $t9, $t8, 1
slt $at, $t9, $a1
sw $t9, 4($sp)
nop
jr $ra
addiu $sp, $sp, 24
addiu $sp, $sp, -24
sw $zero, 4($sp)
lw $t6, 4($sp)
addu $t7, $a0, $t6
sb $zero, ($t7)
lw $t8, 4($sp)
addiu $t9, $t8, 1
slt $at, $t9, $a1
sw $t9, 4($sp)
nop
jr $ra
addiu $sp, $sp, 24
)
void foo(void) {}

View File

@ -0,0 +1,58 @@
tests/large.o: file format elf32-tradbigmips
SYMBOL TABLE:
00000000 l d .text 00000280 .text
00000270 g F .text 00000010 foo
00000000 g F .text 00000270 test
Contents of section .text:
0000 27bdffe8 afa00004 8fae0004 008e7821 '.............x!
0010 a1e00000 8fb80004 27190001 0325082a ........'....%.*
0020 afb90004 00000000 03e00008 27bd0018 ............'...
0030 27bdffe8 afa00004 8fae0004 008e7821 '.............x!
0040 a1e00000 8fb80004 27190001 0325082a ........'....%.*
0050 afb90004 00000000 03e00008 27bd0018 ............'...
0060 27bdffe8 afa00004 8fae0004 008e7821 '.............x!
0070 a1e00000 8fb80004 27190001 0325082a ........'....%.*
0080 afb90004 00000000 03e00008 27bd0018 ............'...
0090 27bdffe8 afa00004 8fae0004 008e7821 '.............x!
00a0 a1e00000 8fb80004 27190001 0325082a ........'....%.*
00b0 afb90004 00000000 03e00008 27bd0018 ............'...
00c0 27bdffe8 afa00004 8fae0004 008e7821 '.............x!
00d0 a1e00000 8fb80004 27190001 0325082a ........'....%.*
00e0 afb90004 00000000 03e00008 27bd0018 ............'...
00f0 27bdffe8 afa00004 8fae0004 008e7821 '.............x!
0100 a1e00000 8fb80004 27190001 0325082a ........'....%.*
0110 afb90004 00000000 03e00008 27bd0018 ............'...
0120 27bdffe8 afa00004 8fae0004 008e7821 '.............x!
0130 a1e00000 8fb80004 27190001 0325082a ........'....%.*
0140 afb90004 00000000 03e00008 27bd0018 ............'...
0150 27bdffe8 afa00004 8fae0004 008e7821 '.............x!
0160 a1e00000 8fb80004 27190001 0325082a ........'....%.*
0170 afb90004 00000000 03e00008 27bd0018 ............'...
0180 27bdffe8 afa00004 8fae0004 008e7821 '.............x!
0190 a1e00000 8fb80004 27190001 0325082a ........'....%.*
01a0 afb90004 00000000 03e00008 27bd0018 ............'...
01b0 27bdffe8 afa00004 8fae0004 008e7821 '.............x!
01c0 a1e00000 8fb80004 27190001 0325082a ........'....%.*
01d0 afb90004 00000000 03e00008 27bd0018 ............'...
01e0 27bdffe8 afa00004 8fae0004 008e7821 '.............x!
01f0 a1e00000 8fb80004 27190001 0325082a ........'....%.*
0200 afb90004 00000000 03e00008 27bd0018 ............'...
0210 27bdffe8 afa00004 8fae0004 008e7821 '.............x!
0220 a1e00000 8fb80004 27190001 0325082a ........'....%.*
0230 afb90004 00000000 03e00008 27bd0018 ............'...
0240 27bdffe8 afa00004 8fae0004 008e7821 '.............x!
0250 a1e00000 8fb80004 27190001 0325082a ........'....%.*
0260 afb90004 00000000 03e00008 27bd0018 ............'...
0270 03e00008 00000000 03e00008 00000000 ................
Contents of section .options:
0000 01200000 00000000 80000000 00000000 . ..............
0010 00000000 00000000 00000000 00007ff0 ................
0020 07100000 00000000 00000000 00000000 ................
0030 08100000 00000000 00000000 00000000 ................
Contents of section .reginfo:
0000 a300c032 00000000 00000000 00000000 ...2............
0010 00000000 00007ff0 ........

View File

@ -0,0 +1,80 @@
GLOBAL_ASM(
.late_rodata
.float 4.1
.float 4.2
.float 4.3
.float 4.4
.text
glabel a
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
)
float foo(void) { "foo"; return 1.1f; }
GLOBAL_ASM(
.late_rodata
.late_rodata_alignment 4
.float 5.1
.float 5.2
.float 5.3
.float 5.4
.text
glabel b
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
)
float bar(void) { "bar"; return 1.2f; }
GLOBAL_ASM(
.late_rodata
.late_rodata_alignment 8
.float 6.1
.float 6.2
.float 6.3
.float 6.4
.float 6.5
.text
glabel c
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
)

View File

@ -0,0 +1,51 @@
tests/late_rodata_align.o: file format elf32-tradbigmips
SYMBOL TABLE:
00000000 l d .text 000000f0 .text
00000000 l d .rodata 00000050 .rodata
00000040 g F .text 0000001c foo
00000090 g F .text 0000001c bar
00000000 g F .text 00000040 a
0000005c g F .text 00000034 b
000000ac g F .text 00000038 c
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
00000040 R_MIPS_HI16 .rodata
00000048 R_MIPS_LO16 .rodata
00000090 R_MIPS_HI16 .rodata
00000098 R_MIPS_LO16 .rodata
Contents of section .text:
0000 00000000 00000000 00000000 00000000 ................
0010 00000000 00000000 00000000 00000000 ................
0020 00000000 00000000 00000000 00000000 ................
0030 00000000 00000000 00000000 00000000 ................
0040 3c010000 03e00008 c4200018 03e00008 <........ ......
0050 00000000 03e00008 00000000 00000000 ................
0060 00000000 00000000 00000000 00000000 ................
0070 00000000 00000000 00000000 00000000 ................
0080 00000000 00000000 00000000 00000000 ................
0090 3c010000 03e00008 c420002c 03e00008 <........ .,....
00a0 00000000 03e00008 00000000 00000000 ................
00b0 00000000 00000000 00000000 00000000 ................
00c0 00000000 00000000 00000000 00000000 ................
00d0 00000000 00000000 00000000 00000000 ................
00e0 00000000 00000000 00000000 00000000 ................
Contents of section .rodata:
0000 666f6f00 62617200 40833333 40866666 foo.bar.@.33@.ff
0010 4089999a 408ccccd 3f8ccccd 40a33333 @...@...?...@.33
0020 40a66666 40a9999a 40accccd 3f99999a @.ff@...@...?...
0030 40c33333 40c66666 40c9999a 40cccccd @.33@.ff@...@...
0040 40d00000 00000000 00000000 00000000 @...............
Contents of section .options:
0000 01200000 00000000 80000002 00000000 . ..............
0010 000005f1 00000000 00000000 00007ff0 ................
0020 07100000 00000000 00000000 00000000 ................
0030 08100000 00000000 00000000 00000000 ................
Contents of section .reginfo:
0000 80000002 00000000 000005f1 00000000 ................
0010 00000000 00007ff0 ........

View File

@ -0,0 +1,83 @@
GLOBAL_ASM(
.late_rodata
.float 4.1
.text
glabel a
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
)
float foo(void) {
return 4.15f;
}
GLOBAL_ASM(
.late_rodata
.float 4.2
.word 0
.double 4.3
.text
glabel b
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
)
float bar(void) {
return 4.4f;
}
GLOBAL_ASM(
.late_rodata
.float 4.55
.double 4.6
.text
glabel c
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
)
float baz(void) {
return 4.6f;
}

View File

@ -0,0 +1,55 @@
tests/late_rodata_doubles.o: file format elf32-tradbigmips
SYMBOL TABLE:
00000000 l d .text 00000120 .text
00000000 l d .rodata 00000030 .rodata
00000040 g F .text 0000001c foo
0000009c g F .text 0000001c bar
000000f8 g F .text 0000001c baz
00000000 g F .text 00000040 a
0000005c g F .text 00000040 b
000000b8 g F .text 00000040 c
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
00000040 R_MIPS_HI16 .rodata
00000048 R_MIPS_LO16 .rodata
0000009c R_MIPS_HI16 .rodata
000000a4 R_MIPS_LO16 .rodata
000000f8 R_MIPS_HI16 .rodata
00000100 R_MIPS_LO16 .rodata
Contents of section .text:
0000 00000000 00000000 00000000 00000000 ................
0010 00000000 00000000 00000000 00000000 ................
0020 00000000 00000000 00000000 00000000 ................
0030 00000000 00000000 00000000 00000000 ................
0040 3c010000 03e00008 c4200004 03e00008 <........ ......
0050 00000000 03e00008 00000000 00000000 ................
0060 00000000 00000000 00000000 00000000 ................
0070 00000000 00000000 00000000 00000000 ................
0080 00000000 00000000 00000000 00000000 ................
0090 00000000 00000000 00000000 3c010000 ............<...
00a0 03e00008 c4200018 03e00008 00000000 ..... ..........
00b0 03e00008 00000000 00000000 00000000 ................
00c0 00000000 00000000 00000000 00000000 ................
00d0 00000000 00000000 00000000 00000000 ................
00e0 00000000 00000000 00000000 00000000 ................
00f0 00000000 00000000 3c010000 03e00008 ........<.......
0100 c4200028 03e00008 00000000 03e00008 . .(............
0110 00000000 00000000 00000000 00000000 ................
Contents of section .rodata:
0000 40833333 4084cccd 40866666 00000000 @.33@...@.ff....
0010 40113333 33333333 408ccccd 4091999a @.333333@...@...
0020 40126666 66666666 40933333 00000000 @.ffffff@.33....
Contents of section .options:
0000 01200000 00000000 80000002 00000000 . ..............
0010 000000f1 00000000 00000000 00007ff0 ................
0020 07100000 00000000 00000000 00000000 ................
0030 08100000 00000000 00000000 00000000 ................
Contents of section .reginfo:
0000 80000002 00000000 000000f1 00000000 ................
0010 00000000 00007ff0 ........

View File

@ -0,0 +1,86 @@
// COMPILE-FLAGS: -O2
// COMPILE-ISET: -mips1
// exact copy of late_rodata_doubles.c except for the -mips1 -O2 additions
GLOBAL_ASM(
.late_rodata
.float 4.1
.text
glabel a
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
)
float foo(void) {
return 4.15f;
}
GLOBAL_ASM(
.late_rodata
.float 4.2
.word 0
.double 4.3
.text
glabel b
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
)
float bar(void) {
return 4.4f;
}
GLOBAL_ASM(
.late_rodata
.float 4.55
.double 4.6
.text
glabel c
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
)
float baz(void) {
return 4.6f;
}

View File

@ -0,0 +1,52 @@
tests/late_rodata_doubles_mips1.o: file format elf32-tradbigmips
SYMBOL TABLE:
00000000 l d .text 000000f0 .text
00000000 l d .rodata 00000030 .rodata
00000040 g F .text 00000010 foo
00000090 g F .text 00000010 bar
000000e0 g F .text 00000010 baz
00000000 g F .text 00000040 a
00000050 g F .text 00000040 b
000000a0 g F .text 00000040 c
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
00000040 R_MIPS_HI16 .rodata
00000044 R_MIPS_LO16 .rodata
00000090 R_MIPS_HI16 .rodata
00000094 R_MIPS_LO16 .rodata
000000e0 R_MIPS_HI16 .rodata
000000e4 R_MIPS_LO16 .rodata
Contents of section .text:
0000 00000000 00000000 00000000 00000000 ................
0010 00000000 00000000 00000000 00000000 ................
0020 00000000 00000000 00000000 00000000 ................
0030 00000000 00000000 00000000 00000000 ................
0040 3c010000 c4200004 03e00008 00000000 <.... ..........
0050 00000000 00000000 00000000 00000000 ................
0060 00000000 00000000 00000000 00000000 ................
0070 00000000 00000000 00000000 00000000 ................
0080 00000000 00000000 00000000 00000000 ................
0090 3c010000 c4200018 03e00008 00000000 <.... ..........
00a0 00000000 00000000 00000000 00000000 ................
00b0 00000000 00000000 00000000 00000000 ................
00c0 00000000 00000000 00000000 00000000 ................
00d0 00000000 00000000 00000000 00000000 ................
00e0 3c010000 c4200028 03e00008 00000000 <.... .(........
Contents of section .rodata:
0000 40833333 4084cccd 40866666 00000000 @.33@...@.ff....
0010 40113333 33333333 408ccccd 4091999a @.333333@...@...
0020 40126666 66666666 40933333 00000000 @.ffffff@.33....
Contents of section .options:
0000 01200000 00000000 80000002 00000000 . ..............
0010 000c0011 00000000 00000000 00007ff0 ................
0020 07100000 00000000 00000000 00000000 ................
0030 08100000 00000000 00000000 00000000 ................
Contents of section .reginfo:
0000 80000002 00000000 000c0011 00000000 ................
0010 00000000 00007ff0 ........

View File

@ -0,0 +1,153 @@
// COMPILE-FLAGS: -O2
GLOBAL_ASM(
.late_rodata
.double 1
.double 2
.double 3
.double 4
.double 5
.double 6
.double 7
.double 8
.text
glabel doubles1
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
)
float a(void) { return 1.1f; }
GLOBAL_ASM(
.late_rodata
.float 1
.double 2
.double 3
.double 4
.double 5
.double 6
.double 7
.double 8
.double 9
.float 10
.text
glabel doubles2
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
)
GLOBAL_ASM(
glabel a2
move $a0, $a0
nop
nop
nop
jr $ra
move $a0, $a0
)
GLOBAL_ASM(
.late_rodata
glabel jtbl
.word case0, case1, case2, case3, case4, case5, case6, case7, case8, case9, case10
.word case11, case12, case13, case14, case15, case16, case17, case18, case19, case20
.word case21, case22, case23, case24, case25, case26
.text
glabel foo
sltiu $at, $a0, 0xa
beqz $at, .L756E659B
sll $t7, $a0, 2
lui $at, %hi(jtbl)
addu $at, $at, $t7
lw $t7, %lo(jtbl)($at)
jr $t7
nop
case0: addiu $a0, $a0, 1
case1: addiu $a0, $a0, 1
case2: addiu $a0, $a0, 1
case3: addiu $a0, $a0, 1
case4: addiu $a0, $a0, 1
case5: addiu $a0, $a0, 1
case6: addiu $a0, $a0, 1
case7: addiu $a0, $a0, 1
case8: addiu $a0, $a0, 1
case9: addiu $a0, $a0, 1
case10: addiu $a0, $a0, 1
case11: addiu $a0, $a0, 1
case12: addiu $a0, $a0, 1
case13: addiu $a0, $a0, 1
case14: addiu $a0, $a0, 1
case15: addiu $a0, $a0, 1
case16: addiu $a0, $a0, 1
case17: addiu $a0, $a0, 1
case18: addiu $a0, $a0, 1
case19: addiu $a0, $a0, 1
case20: addiu $a0, $a0, 1
case21: addiu $a0, $a0, 1
case22: addiu $a0, $a0, 1
case23: addiu $a0, $a0, 1
case24: addiu $a0, $a0, 1
case25: addiu $a0, $a0, 1
case26:
jr $ra
addiu $v0, $a0, 1
.L756E659B:
addiu $v0, $zero, 2
jr $ra
nop
)
GLOBAL_ASM(
glabel b2
move $a0, $a0
nop
nop
jr $ra
move $a0, $a0
)
float b(void) { return 1.2f; }

View File

@ -0,0 +1,110 @@
tests/late_rodata_jtbl.o: file format elf32-tradbigmips
SYMBOL TABLE:
00000000 l d .text 000001a0 .text
00000000 l d .rodata 00000100 .rodata
00000000 l d .text 00000000
0000005c g F .text 0000000c a
0000018c g F .text 0000000c b
00000000 g F .text 0000005c doubles1
00000068 g F .text 0000005c doubles2
000000c4 g F .text 00000018 a2
000000dc g F .text 0000009c foo
0000008c g .rodata 00000000 jtbl
00000178 g F .text 00000014 b2
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
0000005c R_MIPS_HI16 .rodata
00000064 R_MIPS_LO16 .rodata
0000018c R_MIPS_HI16 .rodata
00000194 R_MIPS_LO16 .rodata
000000e8 R_MIPS_HI16 jtbl
000000f0 R_MIPS_LO16 jtbl
RELOCATION RECORDS FOR [.rodata]:
OFFSET TYPE VALUE
0000008c R_MIPS_32
00000090 R_MIPS_32
00000094 R_MIPS_32
00000098 R_MIPS_32
0000009c R_MIPS_32
000000a0 R_MIPS_32
000000a4 R_MIPS_32
000000a8 R_MIPS_32
000000ac R_MIPS_32
000000b0 R_MIPS_32
000000b4 R_MIPS_32
000000b8 R_MIPS_32
000000bc R_MIPS_32
000000c0 R_MIPS_32
000000c4 R_MIPS_32
000000c8 R_MIPS_32
000000cc R_MIPS_32
000000d0 R_MIPS_32
000000d4 R_MIPS_32
000000d8 R_MIPS_32
000000dc R_MIPS_32
000000e0 R_MIPS_32
000000e4 R_MIPS_32
000000e8 R_MIPS_32
000000ec R_MIPS_32
000000f0 R_MIPS_32
000000f4 R_MIPS_32
Contents of section .text:
0000 00000000 00000000 00000000 00000000 ................
0010 00000000 00000000 00000000 00000000 ................
0020 00000000 00000000 00000000 00000000 ................
0030 00000000 00000000 00000000 00000000 ................
0040 00000000 00000000 00000000 00000000 ................
0050 00000000 00000000 00000000 3c010000 ............<...
0060 03e00008 c4200040 00000000 00000000 ..... .@........
0070 00000000 00000000 00000000 00000000 ................
0080 00000000 00000000 00000000 00000000 ................
0090 00000000 00000000 00000000 00000000 ................
00a0 00000000 00000000 00000000 00000000 ................
00b0 00000000 00000000 00000000 00000000 ................
00c0 00000000 00802025 00000000 00000000 ...... %........
00d0 00000000 03e00008 00802025 2c81000a .......... %,...
00e0 10200022 00047880 3c010000 002f0821 . ."..x.<..../.!
00f0 8c2f0000 01e00008 00000000 24840001 ./..........$...
0100 24840001 24840001 24840001 24840001 $...$...$...$...
0110 24840001 24840001 24840001 24840001 $...$...$...$...
0120 24840001 24840001 24840001 24840001 $...$...$...$...
0130 24840001 24840001 24840001 24840001 $...$...$...$...
0140 24840001 24840001 24840001 24840001 $...$...$...$...
0150 24840001 24840001 24840001 24840001 $...$...$...$...
0160 24840001 03e00008 24820001 24020002 $.......$...$...
0170 03e00008 00000000 00802025 00000000 .......... %....
0180 00000000 03e00008 00802025 3c010000 .......... %<...
0190 03e00008 c42000f8 00000000 00000000 ..... ..........
Contents of section .rodata:
0000 3ff00000 00000000 40000000 00000000 ?.......@.......
0010 40080000 00000000 40100000 00000000 @.......@.......
0020 40140000 00000000 40180000 00000000 @.......@.......
0030 401c0000 00000000 40200000 00000000 @.......@ ......
0040 3f8ccccd 3f800000 40000000 00000000 ?...?...@.......
0050 40080000 00000000 40100000 00000000 @.......@.......
0060 40140000 00000000 40180000 00000000 @.......@.......
0070 401c0000 00000000 40200000 00000000 @.......@ ......
0080 40220000 00000000 41200000 000000fc @"......A ......
0090 00000100 00000104 00000108 0000010c ................
00a0 00000110 00000114 00000118 0000011c ................
00b0 00000120 00000124 00000128 0000012c ... ...$...(...,
00c0 00000130 00000134 00000138 0000013c ...0...4...8...<
00d0 00000140 00000144 00000148 0000014c ...@...D...H...L
00e0 00000150 00000154 00000158 0000015c ...P...T...X...\
00f0 00000160 00000164 3f99999a 00000000 ...`...d?.......
Contents of section .options:
0000 01200000 00000000 80004002 00000000 . ........@.....
0010 000000f1 00000000 00000000 00007ff0 ................
0020 07100000 00000000 00000000 00000000 ................
0030 08100000 00000000 00000000 00000000 ................
Contents of section .reginfo:
0000 8000c016 00000000 000000f1 00000000 ................
0010 00000000 00007ff0 ........

View File

@ -0,0 +1,155 @@
// COMPILE-FLAGS: -O2
// COMPILE-ISET: -mips1
// exact copy of late_rodata_jtbl.c except for the -mips1 addition
GLOBAL_ASM(
.late_rodata
.double 1
.double 2
.double 3
.double 4
.double 5
.double 6
.double 7
.double 8
.text
glabel doubles1
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
)
float a(void) { return 1.1f; }
GLOBAL_ASM(
.late_rodata
.float 1
.double 2
.double 3
.double 4
.double 5
.double 6
.double 7
.double 8
.double 9
.float 10
.text
glabel doubles2
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
)
GLOBAL_ASM(
glabel a2
move $a0, $a0
nop
nop
nop
jr $ra
move $a0, $a0
)
GLOBAL_ASM(
.late_rodata
glabel jtbl
.word case0, case1, case2, case3, case4, case5, case6, case7, case8, case9, case10
.word case11, case12, case13, case14, case15, case16, case17, case18, case19, case20
.word case21, case22, case23, case24, case25, case26
.text
glabel foo
sltiu $at, $a0, 0xa
beqz $at, .L756E659B
sll $t7, $a0, 2
lui $at, %hi(jtbl)
addu $at, $at, $t7
lw $t7, %lo(jtbl)($at)
jr $t7
nop
case0: addiu $a0, $a0, 1
case1: addiu $a0, $a0, 1
case2: addiu $a0, $a0, 1
case3: addiu $a0, $a0, 1
case4: addiu $a0, $a0, 1
case5: addiu $a0, $a0, 1
case6: addiu $a0, $a0, 1
case7: addiu $a0, $a0, 1
case8: addiu $a0, $a0, 1
case9: addiu $a0, $a0, 1
case10: addiu $a0, $a0, 1
case11: addiu $a0, $a0, 1
case12: addiu $a0, $a0, 1
case13: addiu $a0, $a0, 1
case14: addiu $a0, $a0, 1
case15: addiu $a0, $a0, 1
case16: addiu $a0, $a0, 1
case17: addiu $a0, $a0, 1
case18: addiu $a0, $a0, 1
case19: addiu $a0, $a0, 1
case20: addiu $a0, $a0, 1
case21: addiu $a0, $a0, 1
case22: addiu $a0, $a0, 1
case23: addiu $a0, $a0, 1
case24: addiu $a0, $a0, 1
case25: addiu $a0, $a0, 1
case26:
jr $ra
addiu $v0, $a0, 1
.L756E659B:
addiu $v0, $zero, 2
jr $ra
nop
)
GLOBAL_ASM(
glabel b2
move $a0, $a0
nop
nop
jr $ra
move $a0, $a0
)
float b(void) { return 1.2f; }

View File

@ -0,0 +1,110 @@
tests/late_rodata_jtbl_mips1.o: file format elf32-tradbigmips
SYMBOL TABLE:
00000000 l d .text 000001a0 .text
00000000 l d .rodata 00000100 .rodata
00000000 l d .text 00000000
0000005c g F .text 00000010 a
00000190 g F .text 00000010 b
00000000 g F .text 0000005c doubles1
0000006c g F .text 0000005c doubles2
000000c8 g F .text 00000018 a2
000000e0 g F .text 0000009c foo
0000008c g .rodata 00000000 jtbl
0000017c g F .text 00000014 b2
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
0000005c R_MIPS_HI16 .rodata
00000060 R_MIPS_LO16 .rodata
00000190 R_MIPS_HI16 .rodata
00000194 R_MIPS_LO16 .rodata
000000ec R_MIPS_HI16 jtbl
000000f4 R_MIPS_LO16 jtbl
RELOCATION RECORDS FOR [.rodata]:
OFFSET TYPE VALUE
0000008c R_MIPS_32
00000090 R_MIPS_32
00000094 R_MIPS_32
00000098 R_MIPS_32
0000009c R_MIPS_32
000000a0 R_MIPS_32
000000a4 R_MIPS_32
000000a8 R_MIPS_32
000000ac R_MIPS_32
000000b0 R_MIPS_32
000000b4 R_MIPS_32
000000b8 R_MIPS_32
000000bc R_MIPS_32
000000c0 R_MIPS_32
000000c4 R_MIPS_32
000000c8 R_MIPS_32
000000cc R_MIPS_32
000000d0 R_MIPS_32
000000d4 R_MIPS_32
000000d8 R_MIPS_32
000000dc R_MIPS_32
000000e0 R_MIPS_32
000000e4 R_MIPS_32
000000e8 R_MIPS_32
000000ec R_MIPS_32
000000f0 R_MIPS_32
000000f4 R_MIPS_32
Contents of section .text:
0000 00000000 00000000 00000000 00000000 ................
0010 00000000 00000000 00000000 00000000 ................
0020 00000000 00000000 00000000 00000000 ................
0030 00000000 00000000 00000000 00000000 ................
0040 00000000 00000000 00000000 00000000 ................
0050 00000000 00000000 00000000 3c010000 ............<...
0060 c4200040 03e00008 00000000 00000000 . .@............
0070 00000000 00000000 00000000 00000000 ................
0080 00000000 00000000 00000000 00000000 ................
0090 00000000 00000000 00000000 00000000 ................
00a0 00000000 00000000 00000000 00000000 ................
00b0 00000000 00000000 00000000 00000000 ................
00c0 00000000 00000000 00802025 00000000 .......... %....
00d0 00000000 00000000 03e00008 00802025 .............. %
00e0 2c81000a 10200022 00047880 3c010000 ,.... ."..x.<...
00f0 002f0821 8c2f0000 01e00008 00000000 ./.!./..........
0100 24840001 24840001 24840001 24840001 $...$...$...$...
0110 24840001 24840001 24840001 24840001 $...$...$...$...
0120 24840001 24840001 24840001 24840001 $...$...$...$...
0130 24840001 24840001 24840001 24840001 $...$...$...$...
0140 24840001 24840001 24840001 24840001 $...$...$...$...
0150 24840001 24840001 24840001 24840001 $...$...$...$...
0160 24840001 24840001 03e00008 24820001 $...$.......$...
0170 24020002 03e00008 00000000 00802025 $............. %
0180 00000000 00000000 03e00008 00802025 .............. %
0190 3c010000 c42000f8 03e00008 00000000 <.... ..........
Contents of section .rodata:
0000 3ff00000 00000000 40000000 00000000 ?.......@.......
0010 40080000 00000000 40100000 00000000 @.......@.......
0020 40140000 00000000 40180000 00000000 @.......@.......
0030 401c0000 00000000 40200000 00000000 @.......@ ......
0040 3f8ccccd 3f800000 40000000 00000000 ?...?...@.......
0050 40080000 00000000 40100000 00000000 @.......@.......
0060 40140000 00000000 40180000 00000000 @.......@.......
0070 401c0000 00000000 40200000 00000000 @.......@ ......
0080 40220000 00000000 41200000 00000100 @"......A ......
0090 00000104 00000108 0000010c 00000110 ................
00a0 00000114 00000118 0000011c 00000120 ...............
00b0 00000124 00000128 0000012c 00000130 ...$...(...,...0
00c0 00000134 00000138 0000013c 00000140 ...4...8...<...@
00d0 00000144 00000148 0000014c 00000150 ...D...H...L...P
00e0 00000154 00000158 0000015c 00000160 ...T...X...\...`
00f0 00000164 00000168 3f99999a 00000000 ...d...h?.......
Contents of section .options:
0000 01200000 00000000 80004002 00000000 . ........@.....
0010 000000f1 00000000 00000000 00007ff0 ................
0020 07100000 00000000 00000000 00000000 ................
0030 08100000 00000000 00000000 00000000 ................
Contents of section .reginfo:
0000 8000c016 00000000 000000f1 00000000 ................
0010 00000000 00007ff0 ........

View File

@ -0,0 +1,77 @@
GLOBAL_ASM(
.late_rodata
.float 4.01
.word 0
.double 4.02
.text
glabel a
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
)
double foo(void) { return 4.03; }
GLOBAL_ASM(
.late_rodata
.float 4.04
.double 4.05
.text
glabel b
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
)
double bar(void) { return 4.06; }
float baz(void) { return 4.07f; }
GLOBAL_ASM(
.late_rodata
.double 4.08
.text
glabel c
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
)

View File

@ -0,0 +1,56 @@
tests/late_rodata_misaligned_doubles.o: file format elf32-tradbigmips
SYMBOL TABLE:
00000000 l d .text 00000120 .text
00000000 l d .rodata 00000040 .rodata
00000040 g F .text 0000001c foo
0000009c g F .text 0000001c bar
000000b8 g F .text 0000001c baz
00000000 g F .text 00000040 a
0000005c g F .text 00000040 b
000000d4 g F .text 00000040 c
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
00000040 R_MIPS_HI16 .rodata
00000048 R_MIPS_LO16 .rodata
0000009c R_MIPS_HI16 .rodata
000000a4 R_MIPS_LO16 .rodata
000000b8 R_MIPS_HI16 .rodata
000000c0 R_MIPS_LO16 .rodata
Contents of section .text:
0000 00000000 00000000 00000000 00000000 ................
0010 00000000 00000000 00000000 00000000 ................
0020 00000000 00000000 00000000 00000000 ................
0030 00000000 00000000 00000000 00000000 ................
0040 3c010000 03e00008 d4200010 03e00008 <........ ......
0050 00000000 03e00008 00000000 00000000 ................
0060 00000000 00000000 00000000 00000000 ................
0070 00000000 00000000 00000000 00000000 ................
0080 00000000 00000000 00000000 00000000 ................
0090 00000000 00000000 00000000 3c010000 ............<...
00a0 03e00008 d4200028 03e00008 00000000 ..... .(........
00b0 03e00008 00000000 3c010000 03e00008 ........<.......
00c0 c4200030 03e00008 00000000 03e00008 . .0............
00d0 00000000 00000000 00000000 00000000 ................
00e0 00000000 00000000 00000000 00000000 ................
00f0 00000000 00000000 00000000 00000000 ................
0100 00000000 00000000 00000000 00000000 ................
0110 00000000 00000000 00000000 00000000 ................
Contents of section .rodata:
0000 408051ec 00000000 4010147a e147ae14 @.Q.....@..z.G..
0010 40101eb8 51eb851f 00000000 408147ae @...Q.......@.G.
0020 40103333 33333333 40103d70 a3d70a3d @.333333@.=p...=
0030 40823d71 00000000 401051eb 851eb852 @.=q....@.Q....R
Contents of section .options:
0000 01200000 00000000 80000002 00000000 . ..............
0010 000000f3 00000000 00000000 00007ff0 ................
0020 07100000 00000000 00000000 00000000 ................
0030 08100000 00000000 00000000 00000000 ................
Contents of section .reginfo:
0000 80000002 00000000 000000f3 00000000 ................
0010 00000000 00007ff0 ........

View File

@ -0,0 +1,4 @@
.rdata
label: .asciiz "1\n\
2", \
"34", "56"

View File

@ -0,0 +1,3 @@
tests/line-continuation.o: tests/line-continuation-separate-file.s
tests/line-continuation-separate-file.s:

View File

@ -0,0 +1,22 @@
void foo(void) { "abcdef"; }
GLOBAL_ASM(
.rdata
.ascii "AB" \
"CD", "EF"
.ascii "GH\n\n\n\0\11\222\3333\44444\x1234567\n\nIJK"
)
void bar(void) { "hello"; }
GLOBAL_ASM(
.rdata
.asciiz "1\
2"
.asciiz "34", "56"
.asciiz "78\n\n\n\0\11\222\3333\44444\x1234567\n\n9A"
)
void baz(void) { "ghijkl"; }
GLOBAL_ASM("tests/line-continuation-separate-file.s")

View File

@ -0,0 +1,30 @@
tests/line-continuation.o: file format elf32-tradbigmips
SYMBOL TABLE:
00000000 l d .text 00000030 .text
00000000 l d .rodata 00000060 .rodata
00000000 g F .text 00000010 foo
00000010 g F .text 00000010 bar
00000020 g F .text 00000010 baz
Contents of section .text:
0000 03e00008 00000000 03e00008 00000000 ................
0010 03e00008 00000000 03e00008 00000000 ................
0020 03e00008 00000000 03e00008 00000000 ................
Contents of section .rodata:
0000 61626364 65660000 41424344 45464748 abcdef..ABCDEFGH
0010 0a0a0a00 0992db33 24343467 0a0a494a .......3$44g..IJ
0020 4b000000 68656c6c 6f000000 31320033 K...hello...12.3
0030 34003536 0037380a 0a0a0009 92db3324 4.56.78.......3$
0040 3434670a 0a394100 6768696a 6b6c0000 44g..9A.ghijkl..
0050 310a3200 33340035 36000000 00000000 1.2.34.56.......
Contents of section .options:
0000 01200000 00000000 80000000 00000000 . ..............
0010 00000000 00000000 00000000 00007ff0 ................
0020 07100000 00000000 00000000 00000000 ................
0030 08100000 00000000 00000000 00000000 ................
Contents of section .reginfo:
0000 80000000 00000000 00000000 00000000 ................
0010 00000000 00007ff0 ........

View File

@ -0,0 +1,28 @@
// COMPILE-FLAGS: -O0
int a(void) { return 1; }
GLOBAL_ASM(
glabel foo
addiu $a0, $a0, 1
addiu $a0, $a0, 2
addiu $a0, $a0, 3
jr $ra
addiu $a0, $a0, 4
)
float b(void) { return 1.2f; }
GLOBAL_ASM(
.late_rodata
glabel float1
.float 12.34
.text
glabel bar
addiu $a0, $a0, 5
addiu $a0, $a0, 6
addiu $a0, $a0, 7
addiu $a0, $a0, 8
lui $v0, %hi(float1 + 1)
jr $ra
addiu $v0, $v0, %lo(float1 + 1)
)
float c(void) { return 1.3f; }

View File

@ -0,0 +1,44 @@
tests/o0.o: file format elf32-tradbigmips
SYMBOL TABLE:
00000000 l d .text 00000090 .text
00000000 l d .rodata 00000010 .rodata
00000000 g F .text 0000001c a
00000030 g F .text 00000020 b
0000006c g F .text 00000020 c
0000001c g F .text 00000014 foo
00000050 g F .text 0000001c bar
00000004 g .rodata 00000000 float1
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
00000030 R_MIPS_HI16 .rodata
00000034 R_MIPS_LO16 .rodata
0000006c R_MIPS_HI16 .rodata
00000070 R_MIPS_LO16 .rodata
00000060 R_MIPS_HI16 float1
00000068 R_MIPS_LO16 float1
Contents of section .text:
0000 24020001 03e00008 00000000 03e00008 $...............
0010 00000000 03e00008 00000000 24840001 ............$...
0020 24840002 24840003 03e00008 24840004 $...$.......$...
0030 3c010000 c4200000 03e00008 00000000 <.... ..........
0040 03e00008 00000000 03e00008 00000000 ................
0050 24840005 24840006 24840007 24840008 $...$...$...$...
0060 3c020000 03e00008 24420001 3c010000 <.......$B..<...
0070 c4200008 03e00008 00000000 03e00008 . ..............
0080 00000000 03e00008 00000000 00000000 ................
Contents of section .rodata:
0000 3f99999a 414570a4 3fa66666 00000000 ?...AEp.?.ff....
Contents of section .options:
0000 01200000 00000000 80000006 00000000 . ..............
0010 00000011 00000000 00000000 00007ff0 ................
0020 07100000 00000000 00000000 00000000 ................
0030 08100000 00000000 00000000 00000000 ................
Contents of section .reginfo:
0000 80000016 00000000 00000011 00000000 ................
0010 00000000 00007ff0 ........

View File

@ -0,0 +1,26 @@
// COMPILE-FLAGS: -O2
int a(void) { return 1; }
GLOBAL_ASM(
glabel foo
addiu $a0, $a0, 1
addiu $a0, $a0, 2
addiu $a0, $a0, 3
jr $ra
addiu $a0, $a0, 4
)
float b(void) { return 1.2f; }
GLOBAL_ASM(
.late_rodata
glabel float1
.float 12.34
.text
glabel bar
addiu $a0, $a0, 5
addiu $a0, $a0, 6
lui $v0, %hi(float1 + 1)
jr $ra
addiu $v0, $v0, %lo(float1 + 1)
)
float c(void) { return 1.3f; }

View File

@ -0,0 +1,40 @@
tests/o2.o: file format elf32-tradbigmips
SYMBOL TABLE:
00000000 l d .text 00000050 .text
00000000 l d .rodata 00000010 .rodata
00000000 g F .text 00000008 a
0000001c g F .text 0000000c b
0000003c g F .text 0000000c c
00000008 g F .text 00000014 foo
00000028 g F .text 00000014 bar
00000004 g .rodata 00000000 float1
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
0000001c R_MIPS_HI16 .rodata
00000024 R_MIPS_LO16 .rodata
0000003c R_MIPS_HI16 .rodata
00000044 R_MIPS_LO16 .rodata
00000030 R_MIPS_HI16 float1
00000038 R_MIPS_LO16 float1
Contents of section .text:
0000 03e00008 24020001 24840001 24840002 ....$...$...$...
0010 24840003 03e00008 24840004 3c010000 $.......$...<...
0020 03e00008 c4200000 24840005 24840006 ..... ..$...$...
0030 3c020000 03e00008 24420001 3c010000 <.......$B..<...
0040 03e00008 c4200008 00000000 00000000 ..... ..........
Contents of section .rodata:
0000 3f99999a 414570a4 3fa66666 00000000 ?...AEp.?.ff....
Contents of section .options:
0000 01200000 00000000 80000006 00000000 . ..............
0010 00000011 00000000 00000000 00007ff0 ................
0020 07100000 00000000 00000000 00000000 ................
0030 08100000 00000000 00000000 00000000 ................
Contents of section .reginfo:
0000 80000016 00000000 00000011 00000000 ................
0010 00000000 00007ff0 ........

View File

@ -0,0 +1,137 @@
tests/pascal.o: file format elf32-tradbigmips
SYMBOL TABLE:
00000000 l d .text 000000e0 .text
00000000 l d .rodata 00000030 .rodata
00000000 l d .data 00000010 .data
00000000 l d .bss 00000010 .bss
00000000 l O .bss 00000000 $dat
00000000 g F .text 0000000c foo
000000d0 g F .text 0000000c bar
0000000c g F .text 00000004 test
00000048 g F .text 00000004 test2
0000008c g F .text 00000044 test3
00000000 *UND* 00000000 get
00000000 *UND* 00000000 put
00000000 *UND* 00000000 pascal_close
00000000 *UND* 00000000 fflush
00000000 *UND* 00000000 filesize
00000000 *UND* 00000000 curpos
00000000 *UND* 00000000 seek
00000000 *UND* 00000000 eof
00000000 *UND* 00000000 eoln
00000000 *UND* 00000000 page
00000000 *UND* 00000000 reset
00000000 *UND* 00000000 rewrite
00000000 *UND* 00000000 cos
00000000 *UND* 00000000 exp
00000000 *UND* 00000000 sqrt
00000000 *UND* 00000000 log
00000000 *UND* 00000000 atan
00000000 *UND* 00000000 sin
00000000 *UND* 00000000 __random_float
00000000 *UND* 00000000 clock
00000000 *UND* 00000000 exit
00000000 *UND* 00000000 __date
00000000 *UND* 00000000 __time
00000000 *UND* 00000000 get_arg
00000000 *UND* 00000000 new
00000000 *UND* 00000000 dispose
00000000 *UND* 00000000 initfile
00000000 *UND* 00000000 peek_char
00000000 *UND* 00000000 next_char
00000000 *UND* 00000000 readln
00000000 *UND* 00000000 read_int64
00000000 *UND* 00000000 read_card64
00000000 *UND* 00000000 read_integer
00000000 *UND* 00000000 read_cardinal
00000000 *UND* 00000000 read_integer_range
00000000 *UND* 00000000 read_real
00000000 *UND* 00000000 read_double
00000000 *UND* 00000000 read_extended
00000000 *UND* 00000000 read_string
00000000 *UND* 00000000 read_enum
00000000 *UND* 00000000 read_char
00000000 *UND* 00000000 read_char_range
00000000 *UND* 00000000 read_boolean
00000000 *UND* 00000000 read_set
00000000 *UND* 00000000 writeln
00000000 *UND* 00000000 write_int64
00000000 *UND* 00000000 write_card64
00000000 *UND* 00000000 write_integer
00000000 *UND* 00000000 write_cardinal
00000000 *UND* 00000000 write_boolean
00000000 *UND* 00000000 write_char
00000000 *UND* 00000000 write_real
00000000 *UND* 00000000 write_double
00000000 *UND* 00000000 write_extended
00000000 *UND* 00000000 write_string
00000000 *UND* 00000000 write_enum
00000000 *UND* 00000000 write_set
00000000 *UND* 00000000 caseerror
00000000 *UND* 00000000 __pc_nloc_goto
00000000 *UND* 00000000 memcpy
00000000 *UND* 00000000 __in_range
00000000 *UND* 00000000 __ll_mul
00000000 *UND* 00000000 __ll_div
00000000 *UND* 00000000 __ull_div
00000000 *UND* 00000000 __ll_mod
00000000 *UND* 00000000 __ll_rem
00000000 *UND* 00000000 __ull_rem
00000000 *UND* 00000000 __ll_lshift
00000000 *UND* 00000000 __ll_rshift
00000000 *UND* 00000000 __ll_to_f
00000000 *UND* 00000000 __ull_to_f
00000000 *UND* 00000000 __ll_to_d
00000000 *UND* 00000000 __ull_to_d
00000000 *UND* 00000000 __f_ll_ll
00000000 *UND* 00000000 __f_to_ull
00000000 *UND* 00000000 __d_to_ll
00000000 *UND* 00000000 __d_to_ull
00000000 *UND* 00000000 round64
00000000 *UND* 00000000 trunc64
00000000 *UND* 00000000 max64
00000000 *UND* 00000000 min64
00000000 *UND* 00000000 abs64
00000000 *UND* 00000000 odd64
00000000 *UND* 00000000 trapNaN
00000000 *UND* 00000008 input
00000000 *UND* 00000008 output
00000000 *UND* 00000008 err
00000000 *UND* 00000008 __Argc
RELOCATION RECORDS FOR [.text]: (none)
RELOCATION RECORDS FOR [.rodata]: (none)
Contents of section .text:
0000 00041080 03e00008 00441023 27bdffe8 .........D.#'...
0010 18a00009 afa00004 8fae0004 008e7821 ..............x!
0020 a1e00000 8fb80004 27190001 0325082a ........'....%.*
0030 1420fff9 afb90004 10000001 00000000 . ..............
0040 03e00008 27bd0018 00000000 00000000 ....'...........
0050 00000000 00000000 00000000 00000000 ................
0060 00000000 00000000 00000000 00000000 ................
0070 00000000 00000000 00000000 00000000 ................
0080 00000000 00000000 00000000 00000000 ................
0090 00000000 00000000 00000000 00000000 ................
00a0 00000000 00000000 00000000 00000000 ................
00b0 00000000 00000000 00000000 00000000 ................
00c0 00000000 00000000 00000000 00000000 ................
00d0 00041080 03e00008 00441023 00000000 .........D.#....
Contents of section .rodata:
0000 00123123 00456456 00789789 00000001 ..1#.EdV.x......
0010 3ff19999 9999999a 00000002 00000003 ?...............
0020 4000cccc cccccccd 00000000 00000000 @...............
Contents of section .data:
0000 00002323 00003434 00000000 00000000 ..##..44........
Contents of section .options:
0000 01200000 00000000 80004016 00000000 . ........@.....
0010 000000f0 00000000 00000000 00007ff0 ................
0020 07100000 00000000 00000000 00000000 ................
0030 08100000 00000000 00000000 00000000 ................
Contents of section .reginfo:
0000 a300c036 00000000 000000f0 00000000 ...6............
0010 00000000 00007ff0 ........

View File

@ -0,0 +1,95 @@
{ COMPILE-FLAGS: -O2 }
function foo(x: integer): integer;
begin
foo := x * 3
end;
GLOBAL_ASM(
.section .data
.word 0x2323
.late_rodata
.word 0x123123
.word 0x456456
.word 0x789789
.text
glabel test
/* 000090 00400090 27BDFFF8 */ addiu $sp, $sp, -24
/* 000094 00400094 18A00009 */ blez $a1, .L004000BC
/* 000098 00400098 AFA00004 */ sw $zero, 4($sp)
.L0040009C:
/* 00009C 0040009C 8FAE0004 */ lw $t6, 4($sp)
/* 0000A0 004000A0 008E7821 */ addu $t7, $a0, $t6
/* 0000A4 004000A4 A1E00000 */ sb $zero, ($t7)
/* 0000A8 004000A8 8FB80004 */ lw $t8, 4($sp)
/* 0000AC 004000AC 27190001 */ addiu $t9, $t8, 1
/* 0000B0 004000B0 0325082A */ slt $at, $t9, $a1
/* 0000B4 004000B4 1420FFF9 */ bnez $at, .L0040009C
/* 0000B8 004000B8 AFB90004 */ sw $t9, 4($sp)
.L004000BC:
/* 0000BC 004000BC 10000001 */ b .L004000C4
/* 0000C0 004000C0 00000000 */ nop
.L004000C4:
/* 0000C4 004000C4 03E00008 */ jr $ra
/* 0000C8 004000C8 27BD0008 */ addiu $sp, $sp, 24
)
GLOBAL_ASM(
.section .data
.word 0x3434
.late_rodata
.word 0x1
.double 1.1
.word 0x2, 0x3
.text
glabel test2
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
)
GLOBAL_ASM(
.late_rodata
.double 2.1
.text
glabel test3
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
)
function bar(x: integer): integer;
begin
return x * 3
end;

View File

@ -0,0 +1,33 @@
// COMPILE-FLAGS: -O2
// ASMP-FLAGS: --convert-statics=global
static int xtext(int a, int b, int c);
const int rodata1[] = {1};
static const int rodata2[] = {2};
int data1[] = {3};
static int data2[] = {4};
int bss1;
static int bss2;
GLOBAL_ASM(
glabel bar
lui $a0, %hi(rodata2)
lw $a0, %lo(rodata2)($a0)
lui $a1, %hi(data2)
lw $a1, %lo(data2)($a0)
lui $a2, %hi(bss2)
lw $a2, %lo(bss2)($a0)
jal xtext
nop
jr $ra
nop
nop
nop
)
static int xtext(int a, int b, int c) {
return 1;
}
void baz(void) {
xtext(bss2, rodata2[0], data2[0]);
}

View File

@ -0,0 +1,58 @@
tests/static-global.o: file format elf32-tradbigmips
SYMBOL TABLE:
00000000 l d .text 00000080 .text
00000000 l d .rodata 00000010 .rodata
00000000 l d .data 00000010 .data
00000000 l d .bss 00000010 .bss
00000000 g O .rodata 00000004 rodata1
00000000 g O .data 00000004 data1
00000000 g O .bss 00000004 bss1
00000044 g F .text 00000034 baz
00000000 g F .text 00000030 bar
00000004 g O .rodata 00000000 rodata2
00000004 g O .data 00000000 data2
00000004 g O .bss 00000000 bss2
00000030 g F .text 00000000 xtext
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
0000004c R_MIPS_HI16 .bss
00000064 R_MIPS_LO16 .bss
00000050 R_MIPS_HI16 .rodata
0000005c R_MIPS_LO16 .rodata
00000054 R_MIPS_HI16 .data
00000058 R_MIPS_LO16 .data
00000060 R_MIPS_26 .text
00000000 R_MIPS_HI16 rodata2
00000004 R_MIPS_LO16 rodata2
00000008 R_MIPS_HI16 data2
0000000c R_MIPS_LO16 data2
00000010 R_MIPS_HI16 bss2
00000014 R_MIPS_LO16 bss2
00000018 R_MIPS_26 xtext
Contents of section .text:
0000 3c040000 8c840000 3c050000 8c850000 <.......<.......
0010 3c060000 8c860000 0c000000 00000000 <...............
0020 03e00008 00000000 00000000 00000000 ................
0030 afa40000 afa50004 afa60008 03e00008 ................
0040 24020001 27bdffe8 afbf0014 3c040000 $...'.......<...
0050 3c050000 3c060000 8cc60004 8ca50004 <...<...........
0060 0c00000c 8c840004 8fbf0014 27bd0018 ............'...
0070 03e00008 00000000 00000000 00000000 ................
Contents of section .rodata:
0000 00000001 00000002 00000000 00000000 ................
Contents of section .data:
0000 00000003 00000004 00000000 00000000 ................
Contents of section .options:
0000 01200000 00000000 a0000074 00000000 . .........t....
0010 00000000 00000000 00000000 00007ff0 ................
0020 07100000 00000000 00000000 00000000 ................
0030 08100000 00000000 00000000 00000000 ................
Contents of section .reginfo:
0000 a0000074 00000000 00000000 00000000 ...t............
0010 00000000 00007ff0 ........

View File

@ -0,0 +1,32 @@
// COMPILE-FLAGS: -O2
static int xtext(int a, int b, int c);
const int rodata1[] = {1};
static const int rodata2[] = {2};
int data1[] = {3};
static int data2[] = {4};
int bss1;
static int bss2;
GLOBAL_ASM(
glabel bar
lui $a0, %hi(rodata2)
lw $a0, %lo(rodata2)($a0)
lui $a1, %hi(data2)
lw $a1, %lo(data2)($a0)
lui $a2, %hi(bss2)
lw $a2, %lo(bss2)($a0)
jal xtext
nop
jr $ra
nop
nop
nop
)
static int xtext(int a, int b, int c) {
return 1;
}
void baz(void) {
xtext(bss2, rodata2[0], data2[0]);
}

View File

@ -0,0 +1,58 @@
tests/static.o: file format elf32-tradbigmips
SYMBOL TABLE:
00000000 l d .text 00000080 .text
00000000 l d .rodata 00000010 .rodata
00000000 l d .data 00000010 .data
00000000 l d .bss 00000010 .bss
00000004 l O .rodata 00000000 rodata2
00000004 l O .data 00000000 data2
00000004 l O .bss 00000000 bss2
00000030 l F .text 00000000 xtext
00000000 g O .rodata 00000004 rodata1
00000000 g O .data 00000004 data1
00000000 g O .bss 00000004 bss1
00000044 g F .text 00000034 baz
00000000 g F .text 00000030 bar
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
0000004c R_MIPS_HI16 .bss
00000064 R_MIPS_LO16 .bss
00000050 R_MIPS_HI16 .rodata
0000005c R_MIPS_LO16 .rodata
00000054 R_MIPS_HI16 .data
00000058 R_MIPS_LO16 .data
00000060 R_MIPS_26 .text
00000000 R_MIPS_HI16 rodata2
00000004 R_MIPS_LO16 rodata2
00000008 R_MIPS_HI16 data2
0000000c R_MIPS_LO16 data2
00000010 R_MIPS_HI16 bss2
00000014 R_MIPS_LO16 bss2
00000018 R_MIPS_26 xtext
Contents of section .text:
0000 3c040000 8c840000 3c050000 8c850000 <.......<.......
0010 3c060000 8c860000 0c000000 00000000 <...............
0020 03e00008 00000000 00000000 00000000 ................
0030 afa40000 afa50004 afa60008 03e00008 ................
0040 24020001 27bdffe8 afbf0014 3c040000 $...'.......<...
0050 3c050000 3c060000 8cc60004 8ca50004 <...<...........
0060 0c00000c 8c840004 8fbf0014 27bd0018 ............'...
0070 03e00008 00000000 00000000 00000000 ................
Contents of section .rodata:
0000 00000001 00000002 00000000 00000000 ................
Contents of section .data:
0000 00000003 00000004 00000000 00000000 ................
Contents of section .options:
0000 01200000 00000000 a0000074 00000000 . .........t....
0010 00000000 00000000 00000000 00007ff0 ................
0020 07100000 00000000 00000000 00000000 ................
0030 08100000 00000000 00000000 00000000 ................
Contents of section .reginfo:
0000 a0000074 00000000 00000000 00000000 ...t............
0010 00000000 00007ff0 ........

View File

@ -0,0 +1,71 @@
GLOBAL_ASM(
.rdata
.word 0x1212
)
GLOBAL_ASM(
.late_rodata
.word 0x123123
.text
glabel test
/* 000090 00400090 27BDFFF8 */ addiu $sp, $sp, -24
/* 000094 00400094 18A00009 */ blez $a1, .L004000BC
/* 000098 00400098 AFA00004 */ sw $zero, 4($sp)
.L0040009C:
/* 00009C 0040009C 8FAE0004 */ lw $t6, 4($sp)
/* 0000A0 004000A0 008E7821 */ addu $t7, $a0, $t6
/* 0000A4 004000A4 A1E00000 */ sb $zero, ($t7)
/* 0000A8 004000A8 8FB80004 */ lw $t8, 4($sp)
/* 0000AC 004000AC 27190001 */ addiu $t9, $t8, 1
/* 0000B0 004000B0 0325082A */ slt $at, $t9, $a1
/* 0000B4 004000B4 1420FFF9 */ bnez $at, .L0040009C
/* 0000B8 004000B8 AFB90004 */ sw $t9, 4($sp)
.L004000BC:
/* 0000BC 004000BC 10000001 */ b .L004000C4
/* 0000C0 004000C0 00000000 */ nop
.L004000C4:
/* 0000C4 004000C4 03E00008 */ jr $ra
/* 0000C8 004000C8 27BD0008 */ addiu $sp, $sp, 24
)
char bss1[3];
GLOBAL_ASM(
.bss
bss2:
.space 3
)
char bss3[3];
char bss4[3];
const int rodata1[2] = {1};
extern int some_rodata;
unsigned g(float, int);
unsigned f(void) {
return g(1.1f, some_rodata);
}
GLOBAL_ASM(
.rdata
glabel some_rodata
.word 0x1313
.text
.late_rodata
.word 0x321321
.text
glabel g
/* 0000C0 004000C0 27BDFFE8 */ addiu $sp, $sp, -0x18
/* 0000C4 004000C4 AFBF0014 */ sw $ra, 0x14($sp)
/* 0000C8 004000C8 240E0004 */ addiu $t6, $zero, 4
/* 0000CC 004000CC 3C010041 */ lui $at, %hi(D_410100)
/* 0000D0 004000D0 AC2E0100 */ sw $t6, %lo(D_410100)($at)
/* 0000D4 004000D4 0C10002C */ jal func_004000B0
/* 0000D8 004000D8 00000000 */ nop
/* 0000DC 004000DC 10000001 */ b .L004000E4
/* 0000E0 004000E0 00000000 */ nop
.L004000E4:
/* 0000E4 004000E4 8FBF0014 */ lw $ra, 0x14($sp)
/* 0000E8 004000E8 27BD0018 */ addiu $sp, $sp, 0x18
/* 0000EC 004000EC 03E00008 */ jr $ra
/* 0000F0 004000F0 00000000 */ nop
)

View File

@ -0,0 +1,54 @@
tests/test1.o: file format elf32-tradbigmips
SYMBOL TABLE:
00000000 l d .text 000000b0 .text
00000000 l d .rodata 00000020 .rodata
00000000 l d .bss 00000010 .bss
00000000 g O .bss 00000003 bss1
00000008 g O .bss 00000003 bss3
0000000c g O .bss 00000003 bss4
00000004 g O .rodata 00000008 rodata1
0000003c g F .text 0000003c f
00000000 g F .text 0000003c test
0000000c g .rodata 00000000 some_rodata
00000078 g F .text 00000004 g
00000000 *UND* 00000000 D_410100
00000000 *UND* 00000000 func_004000B0
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
00000044 R_MIPS_HI16 .rodata
00000054 R_MIPS_LO16 .rodata
00000048 R_MIPS_HI16 some_rodata
0000004c R_MIPS_LO16 some_rodata
00000050 R_MIPS_26 g
00000084 R_MIPS_HI16 D_410100
00000088 R_MIPS_LO16 D_410100
0000008c R_MIPS_26 func_004000B0
Contents of section .text:
0000 27bdffe8 18a00009 afa00004 8fae0004 '...............
0010 008e7821 a1e00000 8fb80004 27190001 ..x!........'...
0020 0325082a 1420fff9 afb90004 10000001 .%.*. ..........
0030 00000000 03e00008 27bd0018 27bdffe8 ........'...'...
0040 afbf0014 3c010000 3c050000 8ca50000 ....<...<.......
0050 0c000000 c42c0014 10000003 00000000 .....,..........
0060 10000001 00000000 8fbf0014 27bd0018 ............'...
0070 03e00008 00000000 27bdffe8 afbf0014 ........'.......
0080 240e0004 3c010000 ac2e0000 0c000000 $...<...........
0090 00000000 10000001 00000000 8fbf0014 ................
00a0 27bd0018 03e00008 00000000 00000000 '...............
Contents of section .rodata:
0000 00001212 00000001 00000000 00001313 ................
0010 00123123 3f8ccccd 00321321 00000000 ..1#?....2.!....
Contents of section .options:
0000 01200000 00000000 a0000022 00000000 . ........."....
0010 00001010 00000000 00000000 00007ff0 ................
0020 07100000 00000000 00000000 00000000 ................
0030 08100000 00000000 00000000 00000000 ................
Contents of section .reginfo:
0000 a300c032 00000000 00001010 00000000 ...2............
0010 00000000 00007ff0 ........

View File

@ -0,0 +1,69 @@
const char buf1[1] = {1};
float func1(void) {
"func1";
return 0.1f;
}
const char buf2[1] = {2};
void func2(void) {
*(volatile float*)0 = -3.5792360305786133f;
*(volatile float*)0 = -3.5792362689971924f;
// "func2";
// return 0.2f;
}
const char buf3[1] = {3};
int func3(int x) {
switch(x) {
case 0:
return 1;
case 1:
return 2;
case 2:
return 3;
case 3:
return 4;
case 4:
return 5;
case 5:
return 4;
case 6:
return 4;
case 7:
return 4;
default:
return 3;
}
}
#if 1
GLOBAL_ASM(
.rdata
.word 0x66756e63 # func
.word 0x34000000 # 4\0\0\0
.word jumptarget + 4
.late_rodata
glabel rv
.word 0x3e4ccccd # 0.2f
.word jumptarget + 8
.text
glabel func4
lui $at, %hi(rv)
glabel jumptarget
jr $ra
lwc1 $f0, %lo(rv)($at)
jr $ra
nop
jr $ra
nop
jr $ra
nop
jr $ra
nop
)
#else
float func4(void) {
"func4";
return 0.2f;
}
#endif

View File

@ -0,0 +1,76 @@
tests/test2.o: file format elf32-tradbigmips
SYMBOL TABLE:
00000000 l d .text 000000f0 .text
00000000 l d .rodata 00000060 .rodata
00000000 g O .rodata 00000001 buf1
00000000 g F .text 0000001c func1
0000000c g O .rodata 00000001 buf2
0000001c g F .text 00000028 func2
00000010 g O .rodata 00000001 buf3
00000044 g F .text 0000007c func3
000000c4 g F .text 00000000 jumptarget
000000c0 g F .text 0000000c func4
0000004c g .rodata 00000000 rv
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
00000000 R_MIPS_HI16 .rodata
00000008 R_MIPS_LO16 .rodata
0000001c R_MIPS_HI16 .rodata
00000020 R_MIPS_LO16 .rodata
00000028 R_MIPS_HI16 .rodata
0000002c R_MIPS_LO16 .rodata
00000054 R_MIPS_HI16 .rodata
0000005c R_MIPS_LO16 .rodata
000000c0 R_MIPS_HI16 rv
000000c8 R_MIPS_LO16 rv
RELOCATION RECORDS FOR [.rodata]:
OFFSET TYPE VALUE
0000002c R_MIPS_32 .text
00000030 R_MIPS_32 .text
00000034 R_MIPS_32 .text
00000038 R_MIPS_32 .text
0000003c R_MIPS_32 .text
00000040 R_MIPS_32 .text
00000044 R_MIPS_32 .text
00000048 R_MIPS_32 .text
0000001c R_MIPS_32 jumptarget
00000050 R_MIPS_32 jumptarget
Contents of section .text:
0000 3c010000 03e00008 c4200020 03e00008 <........ . ....
0010 00000000 03e00008 00000000 3c010000 ............<...
0020 c4240024 e4040000 3c010000 c4260028 .$.$....<....&.(
0030 e4060000 03e00008 00000000 03e00008 ................
0040 00000000 2c810008 10200017 00000000 ....,.... ......
0050 00047080 3c010000 002e0821 8c2e002c ..p.<......!...,
0060 01c00008 00000000 03e00008 24020001 ............$...
0070 03e00008 24020002 03e00008 24020003 ....$.......$...
0080 03e00008 24020004 03e00008 24020005 ....$.......$...
0090 03e00008 24020004 03e00008 24020004 ....$.......$...
00a0 03e00008 24020004 03e00008 24020003 ....$.......$...
00b0 03e00008 00000000 03e00008 00000000 ................
00c0 3c010000 03e00008 c4200000 03e00008 <........ ......
00d0 00000000 03e00008 00000000 03e00008 ................
00e0 00000000 03e00008 00000000 00000000 ................
Contents of section .rodata:
0000 01000000 66756e63 31000000 02000000 ....func1.......
0010 03000000 66756e63 34000000 00000004 ....func4.......
0020 3dcccccd c0651234 c0651235 00000068 =....e.4.e.5...h
0030 00000070 00000078 00000080 00000088 ...p...x........
0040 00000090 00000098 000000a0 3e4ccccd ............>L..
0050 00000008 00000000 00000000 00000000 ................
Contents of section .options:
0000 01200000 00000000 80004016 00000000 . ........@.....
0010 00000051 00000000 00000000 00007ff0 ...Q............
0020 07100000 00000000 00000000 00000000 ................
0030 08100000 00000000 00000000 00000000 ................
Contents of section .reginfo:
0000 80004016 00000000 00000051 00000000 ..@........Q....
0010 00000000 00007ff0 ........

View File

@ -0,0 +1,70 @@
GLOBAL_ASM(
.rdata
.word 321321
.text
glabel test
/* 000090 00400090 27BDFFF8 */ addiu $sp, $sp, -24
/* 000094 00400094 18A00009 */ blez $a1, .L004000BC
/* 000098 00400098 AFA00004 */ sw $zero, 4($sp)
.L0040009C:
/* 00009C 0040009C 8FAE0004 */ lw $t6, 4($sp)
/* 0000A0 004000A0 008E7821 */ addu $t7, $a0, $t6
/* 0000A4 004000A4 A1E00000 */ sb $zero, ($t7)
/* 0000A8 004000A8 8FB80004 */ lw $t8, 4($sp)
/* 0000AC 004000AC 27190001 */ addiu $t9, $t8, 1
/* 0000B0 004000B0 0325082A */ slt $at, $t9, $a1
/* 0000B4 004000B4 1420FFF9 */ bnez $at, .L0040009C
/* 0000B8 004000B8 AFB90004 */ sw $t9, 4($sp)
.L004000BC:
/* 0000BC 004000BC 10000001 */ b .L004000C4
/* 0000C0 004000C0 00000000 */ nop
.L004000C4:
/* 0000C4 004000C4 03E00008 */ jr $ra
/* 0000C8 004000C8 27BD0008 */ addiu $sp, $sp, 24
)
// static -> no symbols
// bss
char globalBuf[4];
const char constBuf[4];
// data
char globalBufInit[4] = {1};
// rodata
const char constBufInit[4] = {1};
const char constBufInit2[1] = {2};
const char constBufInit3[1] = {3};
unsigned g(void);
unsigned f(void) {
// aligns to 4 or 8 byte boundary (char -> 4, double -> 8)
double x = 5.1;
float y = 5.2f;
float z = 5.3f;
"Hello ";
"World";
return g();
}
GLOBAL_ASM(
.rdata
.word 123123
.text
glabel g
/* 0000C0 004000C0 27BDFFE8 */ addiu $sp, $sp, -0x18
/* 0000C4 004000C4 AFBF0014 */ sw $ra, 0x14($sp)
/* 0000C8 004000C8 240E0004 */ addiu $t6, $zero, 4
/* 0000CC 004000CC 3C010041 */ lui $at, %hi(D_410100)
/* 0000D0 004000D0 AC2E0100 */ sw $t6, %lo(D_410100)($at)
/* 0000D4 004000D4 0C10002C */ jal func_004000B0
/* 0000D8 004000D8 00000000 */ nop
/* 0000DC 004000DC 10000001 */ b .L004000E4
/* 0000E0 004000E0 00000000 */ nop
.L004000E4:
/* 0000E4 004000E4 8FBF0014 */ lw $ra, 0x14($sp)
/* 0000E8 004000E8 27BD0018 */ addiu $sp, $sp, 0x18
/* 0000EC 004000EC 03E00008 */ jr $ra
/* 0000F0 004000F0 00000000 */ nop
)

View File

@ -0,0 +1,64 @@
tests/test3.o: file format elf32-tradbigmips
SYMBOL TABLE:
00000000 l d .text 000000d0 .text
00000000 l d .rodata 00000040 .rodata
00000000 l d .data 00000010 .data
00000000 l d .bss 00000010 .bss
00000000 g O .bss 00000004 globalBuf
00000004 g O .bss 00000004 constBuf
00000000 g O .data 00000004 globalBufInit
00000004 g O .rodata 00000004 constBufInit
00000008 g O .rodata 00000001 constBufInit2
0000000c g O .rodata 00000001 constBufInit3
0000003c g F .text 00000054 f
00000000 g F .text 00000004 test
00000090 g F .text 00000004 g
00000000 *UND* 00000000 D_410100
00000000 *UND* 00000000 func_004000B0
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
00000044 R_MIPS_HI16 .rodata
00000048 R_MIPS_LO16 .rodata
00000050 R_MIPS_HI16 .rodata
00000054 R_MIPS_LO16 .rodata
0000005c R_MIPS_HI16 .rodata
00000060 R_MIPS_LO16 .rodata
00000068 R_MIPS_26 g
0000009c R_MIPS_HI16 D_410100
000000a0 R_MIPS_LO16 D_410100
000000a4 R_MIPS_26 func_004000B0
Contents of section .text:
0000 27bdffe8 18a00009 afa00004 8fae0004 '...............
0010 008e7821 a1e00000 8fb80004 27190001 ..x!........'...
0020 0325082a 1420fff9 afb90004 10000001 .%.*. ..........
0030 00000000 03e00008 27bd0018 27bdffd8 ........'...'...
0040 afbf0014 3c010000 d4240028 f7a40020 ....<....$.(...
0050 3c010000 c4260030 e7a6001c 3c010000 <....&.0....<...
0060 c4280034 e7a80018 0c000000 00000000 .(.4............
0070 10000003 00000000 10000001 00000000 ................
0080 8fbf0014 27bd0028 03e00008 00000000 ....'..(........
0090 27bdffe8 afbf0014 240e0004 3c010000 '.......$...<...
00a0 ac2e0000 0c000000 00000000 10000001 ................
00b0 00000000 8fbf0014 27bd0018 03e00008 ........'.......
00c0 00000000 00000000 00000000 00000000 ................
Contents of section .rodata:
0000 0004e729 01000000 02000000 03000000 ...)............
0010 48656c6c 6f202000 576f726c 64000000 Hello .World...
0020 0001e0f3 00000000 40146666 66666666 ........@.ffffff
0030 40a66666 40a9999a 00000000 00000000 @.ff@...........
Contents of section .data:
0000 01000000 00000000 00000000 00000000 ................
Contents of section .options:
0000 01200000 00000000 a0000002 00000000 . ..............
0010 00000170 00000000 00000000 00007ff0 ...p............
0020 07100000 00000000 00000000 00000000 ................
0030 08100000 00000000 00000000 00000000 ................
Contents of section .reginfo:
0000 a300c032 00000000 00000170 00000000 ...2.......p....
0010 00000000 00007ff0 ........