mirror of
https://github.com/rui314/mold.git
synced 2024-09-11 13:06:59 +03:00
Compare commits
2 Commits
2015347b0c
...
49fc7da32e
Author | SHA1 | Date | |
---|---|---|---|
|
49fc7da32e | ||
|
dd56734fda |
@ -394,30 +394,36 @@ inline i64 write_uleb(u8 *buf, u64 val) {
|
||||
return i;
|
||||
}
|
||||
|
||||
inline u64 read_uleb(u8 *&buf) {
|
||||
inline u64 read_uleb(u8 **buf) {
|
||||
u64 val = 0;
|
||||
u8 shift = 0;
|
||||
u8 byte;
|
||||
do {
|
||||
byte = *buf++;
|
||||
byte = *(*buf)++;
|
||||
val |= (byte & 0x7f) << shift;
|
||||
shift += 7;
|
||||
} while (byte & 0x80);
|
||||
return val;
|
||||
}
|
||||
|
||||
inline u64 read_uleb(u8 const*&buf) {
|
||||
return read_uleb(const_cast<u8 *&>(buf));
|
||||
inline u64 read_uleb(u8 *buf) {
|
||||
u8 *tmp = buf;
|
||||
return read_uleb(&tmp);
|
||||
}
|
||||
|
||||
inline u64 read_uleb(std::string_view &str) {
|
||||
u8 *start = (u8 *)&str[0];
|
||||
inline u64 read_uleb(std::string_view *str) {
|
||||
u8 *start = (u8 *)str->data();
|
||||
u8 *ptr = start;
|
||||
u64 val = read_uleb(ptr);
|
||||
str = str.substr(ptr - start);
|
||||
u64 val = read_uleb(&ptr);
|
||||
*str = str->substr(ptr - start);
|
||||
return val;
|
||||
}
|
||||
|
||||
inline u64 read_uleb(std::string_view str) {
|
||||
std::string_view tmp = str;
|
||||
return read_uleb(&tmp);
|
||||
}
|
||||
|
||||
inline i64 uleb_size(u64 val) {
|
||||
#if __GNUC__
|
||||
#pragma GCC unroll 8
|
||||
|
@ -530,12 +530,9 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
|
||||
case R_RISCV_SET_ULEB128:
|
||||
overwrite_uleb(loc, S + A);
|
||||
break;
|
||||
case R_RISCV_SUB_ULEB128: {
|
||||
u8 *p = loc;
|
||||
u64 val = read_uleb(p);
|
||||
overwrite_uleb(loc, val - S - A);
|
||||
case R_RISCV_SUB_ULEB128:
|
||||
overwrite_uleb(loc, read_uleb(loc) - S - A);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
unreachable();
|
||||
}
|
||||
@ -613,12 +610,9 @@ void InputSection<E>::apply_reloc_nonalloc(Context<E> &ctx, u8 *base) {
|
||||
case R_RISCV_SET_ULEB128:
|
||||
overwrite_uleb(loc, S + A);
|
||||
break;
|
||||
case R_RISCV_SUB_ULEB128: {
|
||||
u8 *p = loc;
|
||||
u64 val = read_uleb(p);
|
||||
overwrite_uleb(loc, val - S - A);
|
||||
case R_RISCV_SUB_ULEB128:
|
||||
overwrite_uleb(loc, read_uleb(loc) - S - A);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Fatal(ctx) << *this << ": invalid relocation for non-allocated sections: "
|
||||
<< rel;
|
||||
|
36
elf/dwarf.cc
36
elf/dwarf.cc
@ -216,7 +216,7 @@ find_compunit(Context<E> &ctx, ObjectFile<E> &file, i64 offset) {
|
||||
<< dwarf_version;
|
||||
}
|
||||
|
||||
u32 abbrev_code = read_uleb(cu);
|
||||
u32 abbrev_code = read_uleb(&cu);
|
||||
|
||||
// Find a .debug_abbrev record corresponding to the .debug_info record.
|
||||
// We assume the .debug_info record at a given offset is of
|
||||
@ -224,14 +224,14 @@ find_compunit(Context<E> &ctx, ObjectFile<E> &file, i64 offset) {
|
||||
u8 *abbrev = get_buffer(ctx, ctx.debug_abbrev) + abbrev_offset;
|
||||
|
||||
for (;;) {
|
||||
u32 code = read_uleb(abbrev);
|
||||
u32 code = read_uleb(&abbrev);
|
||||
if (code == 0)
|
||||
Fatal(ctx) << file << ": --gdb-index: .debug_abbrev does not contain"
|
||||
<< " a record for the first .debug_info record";
|
||||
|
||||
if (code == abbrev_code) {
|
||||
// Found a record
|
||||
u64 abbrev_tag = read_uleb(abbrev);
|
||||
u64 abbrev_tag = read_uleb(&abbrev);
|
||||
if (abbrev_tag != DW_TAG_compile_unit && abbrev_tag != DW_TAG_skeleton_unit)
|
||||
Fatal(ctx) << file << ": --gdb-index: the first entry's tag is not"
|
||||
<< " DW_TAG_compile_unit/DW_TAG_skeleton_unit but 0x"
|
||||
@ -240,15 +240,15 @@ find_compunit(Context<E> &ctx, ObjectFile<E> &file, i64 offset) {
|
||||
}
|
||||
|
||||
// Skip an uninteresting record
|
||||
read_uleb(abbrev); // tag
|
||||
read_uleb(&abbrev); // tag
|
||||
abbrev++; // has_children byte
|
||||
for (;;) {
|
||||
u64 name = read_uleb(abbrev);
|
||||
u64 form = read_uleb(abbrev);
|
||||
u64 name = read_uleb(&abbrev);
|
||||
u64 form = read_uleb(&abbrev);
|
||||
if (name == 0 && form == 0)
|
||||
break;
|
||||
if (form == DW_FORM_implicit_const)
|
||||
read_uleb(abbrev);
|
||||
read_uleb(&abbrev);
|
||||
}
|
||||
}
|
||||
|
||||
@ -348,7 +348,7 @@ u64 DebugInfoReader<E>::read(u64 form) {
|
||||
case DW_FORM_ref_udata:
|
||||
case DW_FORM_loclistx:
|
||||
case DW_FORM_rnglistx:
|
||||
return read_uleb(cu);
|
||||
return read_uleb(&cu);
|
||||
case DW_FORM_string:
|
||||
cu += strlen((char *)cu) + 1;
|
||||
return 0;
|
||||
@ -391,19 +391,19 @@ read_rnglist_range(Context<E> &ctx, ObjectFile<E> &file, u8 *rnglist,
|
||||
case DW_RLE_end_of_list:
|
||||
return vec;
|
||||
case DW_RLE_base_addressx:
|
||||
base = addrx[read_uleb(rnglist)];
|
||||
base = addrx[read_uleb(&rnglist)];
|
||||
break;
|
||||
case DW_RLE_startx_endx:
|
||||
vec.push_back(addrx[read_uleb(rnglist)]);
|
||||
vec.push_back(addrx[read_uleb(rnglist)]);
|
||||
vec.push_back(addrx[read_uleb(&rnglist)]);
|
||||
vec.push_back(addrx[read_uleb(&rnglist)]);
|
||||
break;
|
||||
case DW_RLE_startx_length:
|
||||
vec.push_back(addrx[read_uleb(rnglist)]);
|
||||
vec.push_back(vec.back() + read_uleb(rnglist));
|
||||
vec.push_back(addrx[read_uleb(&rnglist)]);
|
||||
vec.push_back(vec.back() + read_uleb(&rnglist));
|
||||
break;
|
||||
case DW_RLE_offset_pair:
|
||||
vec.push_back(base + read_uleb(rnglist));
|
||||
vec.push_back(base + read_uleb(rnglist));
|
||||
vec.push_back(base + read_uleb(&rnglist));
|
||||
vec.push_back(base + read_uleb(&rnglist));
|
||||
break;
|
||||
case DW_RLE_base_address:
|
||||
base = *(Word<E> *)rnglist;
|
||||
@ -418,7 +418,7 @@ read_rnglist_range(Context<E> &ctx, ObjectFile<E> &file, u8 *rnglist,
|
||||
case DW_RLE_start_length:
|
||||
vec.push_back(*(Word<E> *)rnglist);
|
||||
rnglist += sizeof(Word<E>);
|
||||
vec.push_back(vec.back() + read_uleb(rnglist));
|
||||
vec.push_back(vec.back() + read_uleb(&rnglist));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -455,8 +455,8 @@ read_address_areas(Context<E> &ctx, ObjectFile<E> &file, i64 offset) {
|
||||
|
||||
// Read all interesting debug records.
|
||||
for (;;) {
|
||||
u64 name = read_uleb(abbrev);
|
||||
u64 form = read_uleb(abbrev);
|
||||
u64 name = read_uleb(&abbrev);
|
||||
u64 form = read_uleb(&abbrev);
|
||||
if (name == 0 && form == 0)
|
||||
break;
|
||||
|
||||
|
@ -55,9 +55,9 @@ enum : u32 {
|
||||
|
||||
enum : u32 {
|
||||
SHN_UNDEF = 0,
|
||||
SHN_LORESERVE = 0xff00,
|
||||
SHN_ABS = 0xfff1,
|
||||
SHN_COMMON = 0xfff2,
|
||||
SHN_LORESERVE = 0xff00,
|
||||
SHN_XINDEX = 0xffff,
|
||||
};
|
||||
|
||||
|
@ -177,17 +177,17 @@ const char *begin = data.data();
|
||||
p = p.substr(5); // skip the tag and the sub-sub-section size
|
||||
|
||||
while (!p.empty()) {
|
||||
i64 tag = read_uleb(p);
|
||||
i64 tag = read_uleb(&p);
|
||||
|
||||
switch (tag) {
|
||||
case ELF_TAG_RISCV_STACK_ALIGN:
|
||||
file.extra.stack_align = read_uleb(p);
|
||||
file.extra.stack_align = read_uleb(&p);
|
||||
break;
|
||||
case ELF_TAG_RISCV_ARCH:
|
||||
file.extra.arch = read_string(p);
|
||||
break;
|
||||
case ELF_TAG_RISCV_UNALIGNED_ACCESS:
|
||||
file.extra.unaligned_access = read_uleb(p);
|
||||
file.extra.unaligned_access = read_uleb(&p);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -908,7 +908,7 @@ void ObjectFile<E>::mark_addrsig(Context<E> &ctx) {
|
||||
u8 *end = cur + llvm_addrsig->contents.size();
|
||||
|
||||
while (cur != end) {
|
||||
Symbol<E> &sym = *this->symbols[read_uleb(cur)];
|
||||
Symbol<E> &sym = *this->symbols[read_uleb(&cur)];
|
||||
if (sym.file == this)
|
||||
if (InputSection<E> *isec = sym.get_input_section())
|
||||
isec->address_significant = true;
|
||||
|
@ -655,6 +655,11 @@ void SymtabSection<E>::copy_buf(Context<E> &ctx) {
|
||||
// Write the initial NUL byte to .strtab.
|
||||
ctx.buf[ctx.strtab->shdr.sh_offset] = '\0';
|
||||
|
||||
if (ctx.symtab_shndx) {
|
||||
ElfShdr<E> &shdr = ctx.symtab_shndx->shdr;
|
||||
memset(ctx.buf + shdr.sh_offset, 0, shdr.sh_size);
|
||||
}
|
||||
|
||||
// Create section symbols
|
||||
for (Chunk<E> *chunk : ctx.chunks) {
|
||||
if (chunk->shndx) {
|
||||
@ -1606,12 +1611,12 @@ ElfSym<E> to_output_esym(Context<E> &ctx, Symbol<E> &sym, u32 st_name,
|
||||
return SHN_UNDEF;
|
||||
};
|
||||
|
||||
u32 shndx = 0;
|
||||
i64 shndx = -1;
|
||||
if (sym.has_copyrel) {
|
||||
shndx = sym.is_copyrel_readonly ? ctx.copyrel_relro->shndx : ctx.copyrel->shndx;
|
||||
esym.st_value = sym.get_addr(ctx);
|
||||
} else if (sym.file->is_dso || sym.esym().is_undef()) {
|
||||
shndx = SHN_UNDEF;
|
||||
esym.st_shndx = SHN_UNDEF;
|
||||
if (sym.is_canonical)
|
||||
esym.st_value = sym.get_plt_addr(ctx);
|
||||
} else if (Chunk<E> *osec = sym.get_output_section()) {
|
||||
@ -1624,7 +1629,7 @@ ElfSym<E> to_output_esym(Context<E> &ctx, Symbol<E> &sym, u32 st_name,
|
||||
esym.st_value = sym.get_addr(ctx);
|
||||
} else if (!sym.get_input_section()) {
|
||||
// Absolute symbol
|
||||
shndx = SHN_ABS;
|
||||
esym.st_shndx = SHN_ABS;
|
||||
esym.st_value = sym.get_addr(ctx);
|
||||
} else if (sym.get_type() == STT_TLS) {
|
||||
shndx = get_st_shndx(sym);
|
||||
@ -1640,17 +1645,12 @@ ElfSym<E> to_output_esym(Context<E> &ctx, Symbol<E> &sym, u32 st_name,
|
||||
// or greater than SHN_LORESERVE (= 65280), the real index is stored
|
||||
// to a SHT_SYMTAB_SHNDX section which contains a parallel array of
|
||||
// the symbol table.
|
||||
if (shn_xindex) {
|
||||
*shn_xindex = shndx;
|
||||
if (shndx == SHN_UNDEF || shndx == SHN_ABS || shndx == SHN_COMMON)
|
||||
esym.st_shndx = shndx;
|
||||
else
|
||||
esym.st_shndx = SHN_XINDEX;
|
||||
} else {
|
||||
if (shndx >= SHN_LORESERVE && shndx != SHN_ABS && shndx != SHN_COMMON)
|
||||
Fatal(ctx) << sym << ": internal error: output symbol index too large: "
|
||||
<< shndx;
|
||||
if (0 <= shndx && shndx < SHN_LORESERVE) {
|
||||
esym.st_shndx = shndx;
|
||||
} else if (SHN_LORESERVE <= shndx) {
|
||||
assert(shn_xindex);
|
||||
esym.st_shndx = SHN_XINDEX;
|
||||
*shn_xindex = shndx;
|
||||
}
|
||||
|
||||
return esym;
|
||||
|
@ -4,9 +4,16 @@
|
||||
# OneTBB isn't tsan-clean
|
||||
nm mold | grep -q '__tsan_init' && skip
|
||||
|
||||
seq 1 100000 | sed 's/.*/.section .data.\0,"aw"\n.globl x\0\nx\0: .word 0\n/g' | \
|
||||
$CC -c -xassembler -o $t/a.o -
|
||||
echo 'foo = 0x1000' > $t/a.s
|
||||
seq 1 100000 | sed 's/.*/.section .data.\0,"aw"\n.globl x\0\nx\0: .word 0\n/g' >> $t/a.s
|
||||
$CC -c -xassembler -o $t/a.o $t/a.s
|
||||
|
||||
./mold --relocatable -o $t/b.o $t/a.o
|
||||
readelf -WS $t/b.o | grep -Fq .data.100000
|
||||
readelf -Ws $t/b.o | grep -Fq 'GLOBAL DEFAULT 100000'
|
||||
|
||||
readelf -WS $t/b.o > $t/log1
|
||||
grep -Fq .data.100000 $t/log1
|
||||
|
||||
readelf -Ws $t/b.o > $t/log2
|
||||
grep -Fq 'GLOBAL DEFAULT 100000' $t/log2
|
||||
grep -Fq 'ABS foo' $t/log2
|
||||
! grep -Fq 'ABS x68966' $t/log2 || false
|
||||
|
Loading…
Reference in New Issue
Block a user