Skip to content

Commit

Permalink
Add support for -mcmodel=large relocations
Browse files Browse the repository at this point in the history
Issue #27
  • Loading branch information
davidlattimore committed Aug 13, 2024
1 parent c9cadf8 commit 0eadaae
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 9 deletions.
4 changes: 4 additions & 0 deletions wild/tests/sources/cpp-integration.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
//#CompArgs:-fno-pie -fmerge-constants
//#LinkArgs:--cc=g++ -no-pie -Wl,-z,now

//#Config:model-large:default
//#CompArgs:-mcmodel=large
//#LinkArgs:--cc=g++ -Wl,-z,now

#include <iostream>
#include <string>

Expand Down
30 changes: 28 additions & 2 deletions wild_lib/src/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,10 +382,25 @@ const _ASSERTS: () = {
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum RelocationKind {
Absolute,

/// The address of the symbol, relative to the place of the relocation.
Relative,
Got,

/// The address of the symbol, relative to the base address of the GOT.
SymRelGotBase,

/// The offset of the symbol's GOT entry, relative to the start of the GOT.
GotRelGotBase,

/// The address of the symbol's PLT entry, relative to the base address of the GOT.
PltRelGotBase,

/// The address of the symbol's PLT entry, relative to the place of relocation.
PltRelative,

/// The address of the symbol's GOT entry, relative to the place of the relocation.
GotRelative,

TlsGd,
TlsLd,
DtpOff,
Expand All @@ -408,9 +423,20 @@ impl RelocationKindInfo {
let (kind, size) = match r_type {
object::elf::R_X86_64_64 => (RelocationKind::Absolute, 8),
object::elf::R_X86_64_PC32 => (RelocationKind::Relative, 4),
object::elf::R_X86_64_GOT32 => (RelocationKind::Got, 4),
object::elf::R_X86_64_PC64 => (RelocationKind::Relative, 8),
object::elf::R_X86_64_GOT32 => (RelocationKind::GotRelGotBase, 4),
object::elf::R_X86_64_GOT64 => (RelocationKind::GotRelGotBase, 8),
object::elf::R_X86_64_GOTOFF64 => (RelocationKind::SymRelGotBase, 8),
object::elf::R_X86_64_PLT32 => (RelocationKind::PltRelative, 4),
object::elf::R_X86_64_PLTOFF64 => (RelocationKind::PltRelGotBase, 8),
object::elf::R_X86_64_GOTPCREL => (RelocationKind::GotRelative, 4),

// For now, we rely on GOTPC64 and GOTPC32 always referencing the symbol
// _GLOBAL_OFFSET_TABLE_, which means that we can just treat these a normal relative
// relocations and avoid any special processing when writing.
object::elf::R_X86_64_GOTPC64 => (RelocationKind::Relative, 8),
object::elf::R_X86_64_GOTPC32 => (RelocationKind::Relative, 4),

object::elf::R_X86_64_32 | object::elf::R_X86_64_32S => (RelocationKind::Absolute, 4),
object::elf::R_X86_64_16 => (RelocationKind::Absolute, 2),
object::elf::R_X86_64_PC16 => (RelocationKind::Relative, 2),
Expand Down
7 changes: 6 additions & 1 deletion wild_lib/src/elf_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1502,6 +1502,12 @@ fn apply_relocation(
.got_address()?
.wrapping_add(addend)
.wrapping_sub(place),
RelocationKind::GotRelGotBase => resolution
.got_address()?
.sub(layout.got_base())
.wrapping_add(addend),
RelocationKind::SymRelGotBase => resolution.value().wrapping_sub(layout.got_base()),
RelocationKind::PltRelGotBase => resolution.plt_address()?.wrapping_sub(layout.got_base()),
RelocationKind::PltRelative => resolution
.plt_address()?
.wrapping_add(addend)
Expand Down Expand Up @@ -1534,7 +1540,6 @@ fn apply_relocation(
.wrapping_sub(layout.tls_end_address())
.wrapping_add(addend),
RelocationKind::None => 0,
other => bail!("Unsupported relocation kind {other:?}"),
};
let value_bytes = value.to_le_bytes();
let end = offset_in_section as usize + rel_info.byte_size;
Expand Down
21 changes: 15 additions & 6 deletions wild_lib/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1211,6 +1211,11 @@ impl<'data> Layout<'data> {
let group_layout = &self.group_layouts[file_id.group()];
&group_layout.files[file_id.file()]
}

/// Returns the base address of the global offset table.
pub(crate) fn got_base(&self) -> u64 {
self.section_layouts.get(output_section_id::GOT).mem_offset
}
}

fn layout_sections(
Expand Down Expand Up @@ -2161,15 +2166,19 @@ fn process_relocation(

fn resolution_flags(rel_kind: RelocationKind) -> ResolutionFlags {
match rel_kind {
RelocationKind::PltRelative => ResolutionFlags::PLT | ResolutionFlags::GOT,
RelocationKind::Got | RelocationKind::GotRelative => ResolutionFlags::GOT,
RelocationKind::PltRelative | RelocationKind::PltRelGotBase => {
ResolutionFlags::PLT | ResolutionFlags::GOT
}
RelocationKind::GotRelGotBase | RelocationKind::GotRelative => ResolutionFlags::GOT,
RelocationKind::GotTpOff => ResolutionFlags::GOT_TLS_OFFSET,
RelocationKind::TlsGd => ResolutionFlags::GOT_TLS_MODULE,
RelocationKind::TlsLd => ResolutionFlags::empty(),
RelocationKind::Absolute => ResolutionFlags::DIRECT,
RelocationKind::Relative => ResolutionFlags::DIRECT,
RelocationKind::DtpOff | RelocationKind::TpOff => ResolutionFlags::DIRECT,
RelocationKind::None => ResolutionFlags::DIRECT,
RelocationKind::Absolute
| RelocationKind::Relative
| RelocationKind::DtpOff
| RelocationKind::TpOff
| RelocationKind::SymRelGotBase
| RelocationKind::None => ResolutionFlags::DIRECT,
}
}

Expand Down

0 comments on commit 0eadaae

Please sign in to comment.