Collapse nested ifs into let chains

This commit is contained in:
Rui Ueyama committed 2026-09-18 16:58:23 +09:00
1 parent 61c0854ddc
commit ebbda8f4bc
19 files changed
+280 -287

No files matched your search

+8 -10
View File
@@ -43,17 +43,15 @@ fn git_hash(source_dir: &Path) -> Option<String> {
let reftable = git_path("reftable/tables.list").filter(|p| p.exists());
if let Some(head) = git_path("HEAD").filter(|p| p.exists()) {
println!("cargo:rerun-if-changed={}", head.display());
if let Ok(contents) = std::fs::read_to_string(&head) {
if let Some(reference) =
if let Ok(contents) = std::fs::read_to_string(&head)
&& let Some(reference) =
contents.strip_prefix("ref: ").map(str::trim).filter(|_| reftable.is_none())
{
if let Some(path) = git_path(reference) {
// A packed reference may acquire a loose file later.
// Watch its nearest existing directory until that happens.
if let Some(path) = path.ancestors().find(|p| p.exists()) {
println!("cargo:rerun-if-changed={}", path.display());
}
}
&& let Some(path) = git_path(reference)
{
// A packed reference may acquire a loose file later.
// Watch its nearest existing directory until that happens.
if let Some(path) = path.ancestors().find(|p| p.exists()) {
println!("cargo:rerun-if-changed={}", path.display());
}
}
}
+5 -4
View File
@@ -67,10 +67,11 @@ pub fn copy_buf<E: Arch>(ctx: &Context<E>, buf: &mut [u8], eh_frame_buf: Option<
rel.set_r_sym(r_sym);
if E::IS_RELA {
rel.set_r_addend(addend);
} else if ctx.args.relocatable && is_section {
if let Some(eh) = eh_frame_buf {
E::write_addend(&mut eh[offset as usize..], addend, r);
}
} else if ctx.args.relocatable
&& is_section
&& let Some(eh) = eh_frame_buf
{
E::write_addend(&mut eh[offset as usize..], addend, r);
}
out[n] = rel;
n += 1;
+9 -9
View File
@@ -149,16 +149,16 @@ fn for_each_entry<E: Arch>(ctx: &Context<E>, mut emit: impl FnMut(GotEntry)) {
let idx = sym.got_idx(&ctx.symbols).unwrap();
// IFUNC always needs to be fixed up by the dynamic linker.
if let Some(r_irelative) = E::R_IRELATIVE {
if sym.is_ifunc() {
if sym.is_pde_ifunc(ctx) {
add(idx, sym.plt_addr(ctx), R_NONE, None);
add(idx + 1, sym.addr_with(ctx, AddrFlags::NO_PLT), r_irelative, None);
} else {
add(idx, sym.addr_with(ctx, AddrFlags::NO_PLT), r_irelative, None);
}
continue;
if let Some(r_irelative) = E::R_IRELATIVE
&& sym.is_ifunc()
{
if sym.is_pde_ifunc(ctx) {
add(idx, sym.plt_addr(ctx), R_NONE, None);
add(idx + 1, sym.addr_with(ctx, AddrFlags::NO_PLT), r_irelative, None);
} else {
add(idx, sym.addr_with(ctx, AddrFlags::NO_PLT), r_irelative, None);
}
continue;
}
if sym.is_imported() {
+36 -36
View File
@@ -322,10 +322,10 @@ fn write_shdr<E: Arch>(ctx: &Context<E>, buf: &mut [u8]) {
buf.fill(0);
let mut first = ElfShdr::<E>::default();
if let Some(shstrtab) = &ctx.shstrtab {
if shstrtab.shndx >= SHN_LORESERVE {
first.sh_link.set(shstrtab.shndx);
}
if let Some(shstrtab) = &ctx.shstrtab
&& shstrtab.shndx >= SHN_LORESERVE
{
first.sh_link.set(shstrtab.shndx);
}
let shnum = buf.len() / size;
if shnum > u16::MAX as usize {
@@ -427,10 +427,10 @@ fn create_phdr<E: Arch>(ctx: &Context<E>) -> Vec<ElfPhdr<E>> {
chunks.sort_by_key(|&id| ctx.chunk_header(id).shdr.sh_addr.get());
// Create a PT_PHDR for the program header itself.
if let Some(phdr) = &ctx.phdr {
if phdr.hdr.is_alloc() {
define(&mut vec, PT_PHDR, PF_R, &phdr.hdr.shdr);
}
if let Some(phdr) = &ctx.phdr
&& phdr.hdr.is_alloc()
{
define(&mut vec, PT_PHDR, PF_R, &phdr.hdr.shdr);
}
// Create a PT_INTERP.
@@ -507,11 +507,11 @@ fn create_phdr<E: Arch>(ctx: &Context<E>) -> Vec<ElfPhdr<E>> {
}
// Add PT_DYNAMIC
if let Some(osec) = &ctx.dynamic {
if osec.shdr.sh_size.get() != 0 {
let flags = to_phdr_flags(ctx, ChunkId::Dynamic);
define(&mut vec, PT_DYNAMIC, flags, &osec.shdr);
}
if let Some(osec) = &ctx.dynamic
&& osec.shdr.sh_size.get() != 0
{
let flags = to_phdr_flags(ctx, ChunkId::Dynamic);
define(&mut vec, PT_DYNAMIC, flags, &osec.shdr);
}
// Add PT_GNU_EH_FRAME
@@ -530,10 +530,10 @@ fn create_phdr<E: Arch>(ctx: &Context<E>) -> Vec<ElfPhdr<E>> {
}
// Create a PT_RISCV_ATTRIBUTES
if let Some(osec) = &ctx.riscv_attributes {
if osec.hdr.shdr.sh_size.get() != 0 {
define(&mut vec, PT_RISCV_ATTRIBUTES, PF_R, &osec.hdr.shdr);
}
if let Some(osec) = &ctx.riscv_attributes
&& osec.hdr.shdr.sh_size.get() != 0
{
define(&mut vec, PT_RISCV_ATTRIBUTES, PF_R, &osec.hdr.shdr);
}
// Create a PT_ARM_EDXIDX
@@ -596,26 +596,26 @@ fn create_phdr<E: Arch>(ctx: &Context<E>) -> Vec<ElfPhdr<E>> {
// that they can be directly read/executed from ROM. If a gap between
// two segments is two page size or larger, we give up and pack segments
// tightly so that we don't waste too much ROM area.
if let Some(base) = ctx.args.physical_image_base {
if let Some(first) = vec.iter().position(|p| p.p_type().get() == PT_LOAD) {
let mut addr = base;
let mut in_sync = vec[first].p_vaddr().get() == addr;
vec[first].p_paddr_mut().set(addr);
addr += vec[first].p_memsz().get();
if let Some(base) = ctx.args.physical_image_base
&& let Some(first) = vec.iter().position(|p| p.p_type().get() == PT_LOAD)
{
let mut addr = base;
let mut in_sync = vec[first].p_vaddr().get() == addr;
vec[first].p_paddr_mut().set(addr);
addr += vec[first].p_memsz().get();
for p in vec[first + 1..].iter_mut().take_while(|p| p.p_type().get() == PT_LOAD) {
if in_sync
&& addr <= p.p_vaddr().get()
&& p.p_vaddr().get() < addr + ctx.args.page_size * 2
{
let vaddr = p.p_vaddr().get();
p.p_paddr_mut().set(vaddr);
addr = vaddr + p.p_memsz().get();
} else {
in_sync = false;
p.p_paddr_mut().set(addr);
addr += p.p_memsz().get();
}
for p in vec[first + 1..].iter_mut().take_while(|p| p.p_type().get() == PT_LOAD) {
if in_sync
&& addr <= p.p_vaddr().get()
&& p.p_vaddr().get() < addr + ctx.args.page_size * 2
{
let vaddr = p.p_vaddr().get();
p.p_paddr_mut().set(vaddr);
addr = vaddr + p.p_memsz().get();
} else {
in_sync = false;
p.p_paddr_mut().set(addr);
addr += p.p_memsz().get();
}
}
}
+28 -28
View File
@@ -83,11 +83,11 @@ fn symidx_addend<'a, E: Arch>(
let file = &ctx.objs[isec.file.index()];
let sym = &ctx.symbols[file.base.symbols[rel.r_sym() as usize]];
if !isec.is_alloc() {
if let Some((frag, addend)) = isec.fragment(ctx, rel, cache) {
let msec = &ctx.merged_sections[frag.section.index()];
return (msec.hdr.shndx, msec.fragments.get(frag.entry).offset() as i64 + addend);
}
if !isec.is_alloc()
&& let Some((frag, addend)) = isec.fragment(ctx, rel, cache)
{
let msec = &ctx.merged_sections[frag.section.index()];
return (msec.hdr.shndx, msec.fragments.get(frag.entry).offset() as i64 + addend);
}
if sym.st_type() == STT_SECTION {
@@ -107,24 +107,6 @@ fn symidx_addend<'a, E: Arch>(
output_symidx_addend(ctx, sym, || isec.rel_addend(rel)).unwrap_or((0, 0))
}
#[cfg(test)]
mod tests {
use super::*;
use crate::arch::I386;
use crate::cmdline::Args;
#[test]
fn discarded_section_does_not_read_implicit_addend() {
let ctx = Context::<I386>::new(Args::default(), Vec::new());
let mut sym = Symbol::new(BStr::new(b".text"));
let mut esym = ElfSym::<I386>::default();
esym.set_type(STT_SECTION);
sym.set_esym(&esym);
assert_eq!(output_symidx_addend(&ctx, &sym, || panic!("read discarded relocation")), None);
}
}
/// Writes the relocations. With `-r` on a REL target, the addends are
/// written into the output section's bytes, passed as `osec_buf`.
pub fn copy_buf<E: Arch>(ctx: &Context<E>, i: u32, buf: &mut [u8], osec_buf: Option<&mut [u8]>) {
@@ -154,12 +136,30 @@ pub fn copy_buf<E: Arch>(ctx: &Context<E>, i: u32, buf: &mut [u8], osec_buf: Opt
let out_addend = if E::FAMILY == crate::arch::Family::Sh4 { 0 } else { addend };
out[base + j] = ElfRel::<E>::new(r_offset, rel.r_type(), symidx, out_addend);
if ctx.args.relocatable {
if let Some(osec_buf) = osec_buf.as_deref_mut() {
let loc = (isec.offset() + rel.r_offset()) as usize;
E::write_addend(&mut osec_buf[loc..], addend, rel);
}
if ctx.args.relocatable
&& let Some(osec_buf) = osec_buf.as_deref_mut()
{
let loc = (isec.offset() + rel.r_offset()) as usize;
E::write_addend(&mut osec_buf[loc..], addend, rel);
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::arch::I386;
use crate::cmdline::Args;
#[test]
fn discarded_section_does_not_read_implicit_addend() {
let ctx = Context::<I386>::new(Args::default(), Vec::new());
let mut sym = Symbol::new(BStr::new(b".text"));
let mut esym = ElfSym::<I386>::default();
esym.set_type(STT_SECTION);
sym.set_esym(&esym);
assert_eq!(output_symidx_addend(&ctx, &sym, || panic!("read discarded relocation")), None);
}
}
+9 -9
View File
@@ -199,15 +199,15 @@ fn carve<'a>(rest: &mut &'a mut [u8], pos: &mut usize, start: usize, len: usize)
// size as well.
fn symbol_size<E: Arch>(ctx: &Context<E>, sym: &Symbol) -> u64 {
let esym = &sym.esym(ctx);
if (E::IS_RISCV || E::IS_LOONGARCH) && esym.st_size().get() != 0 {
if let Some(isec) = sym.input_section_ref(ctx) {
if isec.sh_flags & SHF_EXECINSTR as u64 != 0 {
let end = esym.st_value().get() + esym.st_size().get();
return (esym.st_size().get() as i64 + esym.st_value().get() as i64
- sym.value as i64
- r_delta(isec, end)) as u64;
}
}
if (E::IS_RISCV || E::IS_LOONGARCH)
&& esym.st_size().get() != 0
&& let Some(isec) = sym.input_section_ref(ctx)
&& isec.sh_flags & SHF_EXECINSTR as u64 != 0
{
let end = esym.st_value().get() + esym.st_size().get();
return (esym.st_size().get() as i64 + esym.st_value().get() as i64
- sym.value as i64
- r_delta(isec, end)) as u64;
}
esym.st_size().get()
}
+4 -4
View File
@@ -1933,10 +1933,10 @@ pub fn parse_args(target: &TargetTraits, raw_cmdline: &[Cow<'_, OsStr>]) -> Pars
parse_report_output(path.as_os_str()).unwrap_or(ReportOutput::Stdout)
});
if !directory.as_os_str().is_empty() {
if let Err(e) = std::env::set_current_dir(&directory) {
fatal!("chdir failed: {}: {e}", directory.display());
}
if !directory.as_os_str().is_empty()
&& let Err(e) = std::env::set_current_dir(&directory)
{
fatal!("chdir failed: {}: {e}", directory.display());
}
if !a.sysroot.as_os_str().is_empty() {
+12 -12
View File
@@ -111,18 +111,18 @@ fn is_gcc_lto_obj<E: Layout>(data: &[u8], has_gcc_plugin: bool) -> bool {
let syms = records_from_bytes::<ElfSym<E>>(bytes).iter();
let skip = |ty: u32| ty == STT_NOTYPE || ty == STT_FILE || ty == STT_SECTION;
if let Some(sym) = syms.skip(1).find(|s| !skip(s.st_type())) {
if sym.st_shndx().get() as u32 == SHN_COMMON {
let Some(strtab) = shdrs.get(shdr.sh_link.get() as usize) else {
return false;
};
let name = crate::util::cstr_at(
data,
strtab.sh_offset.get() as usize + sym.st_name().get() as usize,
);
if name.starts_with(b"__gnu_lto_") {
return true;
}
if let Some(sym) = syms.skip(1).find(|s| !skip(s.st_type()))
&& sym.st_shndx().get() as u32 == SHN_COMMON
{
let Some(strtab) = shdrs.get(shdr.sh_link.get() as usize) else {
return false;
};
let name = crate::util::cstr_at(
data,
strtab.sh_offset.get() as usize + sym.st_name().get() as usize,
);
if name.starts_with(b"__gnu_lto_") {
return true;
}
}
break;
+20 -20
View File
@@ -189,30 +189,30 @@ fn visit_section<'scope, E: Arch>(
// defined. A single such reference can keep an enormous number of
// sections alive, so we spread the fanout over threads instead
// of marking the sections one by one.
if let Some(name) = start_stop_name(sym.name()) {
if let Some(sections) = map.get(name) {
// Mark targets in parallel. mark_section returns true only for
// newly marked sections, which the batch visitor must then visit
// unconditionally.
sections.par_chunks(GC_BATCH).for_each(|sections| {
let mut found = Vec::with_capacity(sections.len());
for &target in sections {
if mark_section(target) {
found.push(target);
}
if let Some(name) = start_stop_name(sym.name())
&& let Some(sections) = map.get(name)
{
// Mark targets in parallel. mark_section returns true only for
// newly marked sections, which the batch visitor must then visit
// unconditionally.
sections.par_chunks(GC_BATCH).for_each(|sections| {
let mut found = Vec::with_capacity(sections.len());
for &target in sections {
if mark_section(target) {
found.push(target);
}
if !found.is_empty() {
visit_batch(ctx, &found, map, scope);
}
});
}
}
if !found.is_empty() {
visit_batch(ctx, &found, map, scope);
}
});
}
}
if E::FAMILY == Family::Arm32 {
if let Some(exidx) = isec.exidx() {
mark(file.section_at(exidx));
}
if E::FAMILY == Family::Arm32
&& let Some(exidx) = isec.exidx()
{
mark(file.section_at(exidx));
}
}
+13 -13
View File
@@ -1360,11 +1360,11 @@ impl<E: Arch> ObjectFile<E> {
/// Marks a section dead along with its FDEs.
pub fn kill_section(&self, shndx: usize) {
if let Some(isec) = self.section(shndx) {
if isec.kill() {
for fde in isec.fdes(self) {
fde.kill();
}
if let Some(isec) = self.section(shndx)
&& isec.kill()
{
for fde in isec.fdes(self) {
fde.kill();
}
}
}
@@ -2005,10 +2005,10 @@ impl<E: Arch> ObjectFile<E> {
sym.set_sym_idx(i as u32);
sym.set_esym(esym);
sym.set_rust(self.is_rust_obj);
if let Some(shndx) = shndx {
if let Some(section) = self.section_id(shndx) {
sym.set_input_section(section);
}
if let Some(shndx) = shndx
&& let Some(section) = self.section_id(shndx)
{
sym.set_input_section(section);
}
slots[next].write(sym);
self.base.symbols[i] = SymbolId(base_id.0 + next as u32);
@@ -2848,10 +2848,10 @@ fn should_write_to_local_symtab<E: Arch>(ctx: &Context<E>, sym: &Symbol) -> bool
if ctx.args.discard_locals {
return false;
}
if let Some(isec) = sym.input_section_ref(ctx) {
if isec.sh_flags & SHF_MERGE as u64 != 0 {
return false;
}
if let Some(isec) = sym.input_section_ref(ctx)
&& isec.sh_flags & SHF_MERGE as u64 != 0
{
return false;
}
}
true
+5 -4
View File
@@ -849,10 +849,11 @@ impl<E: Arch> InputSection<E> {
// If the section was dead due to ICF, we don't want to emit debug
// info for that section but want to set real values to .debug_line so
// that users can set a breakpoint inside a merged section.
if let Some(isec) = isec {
if isec.is_icf_removed() && name == b".debug_line" {
return None;
}
if let Some(isec) = isec
&& isec.is_icf_removed()
&& name == b".debug_line"
{
return None;
}
// 0 is an invalid value in most debug info sections, so we use it
+15 -16
View File
@@ -141,17 +141,16 @@ fn resolve_path<E: Arch>(
let chroot = &ctx.args.chroot;
let open = |path: &Path| -> Option<&'static MappedFile> {
let mf = open_file(chroot, path)?;
if check_target {
if let Some(target) = reader::get_machine_type(ctx, rctx, mf) {
if target != E::NAME {
warn!(
"{}: skipping incompatible file: {target} (e_machine {})",
path.display(),
E::E_MACHINE
);
return None;
}
}
if check_target
&& let Some(target) = reader::get_machine_type(ctx, rctx, mf)
&& target != E::NAME
{
warn!(
"{}: skipping incompatible file: {target} (e_machine {})",
path.display(),
E::E_MACHINE
);
return None;
}
Some(mf)
};
@@ -425,11 +424,11 @@ impl<'a, E: Arch> Script<'a, E> {
tok = self.skip(tok, "{");
tok = self.read_version_script_commands(tok, ver_str, ver_idx, true, false);
tok = self.skip(tok, "}");
if let Some(&t) = tok.first() {
if t != b";" {
// A parent version, e.g. `} VER_1.0;`
tok = &tok[1..];
}
if let Some(&t) = tok.first()
&& t != b";"
{
// A parent version, e.g. `} VER_1.0;`
tok = &tok[1..];
}
tok = self.skip(tok, ";");
}
+5 -4
View File
@@ -22,10 +22,11 @@ fn section_symbols<E: Arch>(ctx: &Context<E>) -> HashMap<InputSectionId, Vec<Sym
let file_id = FileId::Obj(file.id());
for &id in &file.base.symbols {
let sym = &ctx.symbols[id];
if sym.file() == Some(file_id) && sym.ty() != STT_SECTION {
if let Some(r) = sym.input_section() {
map.entry(r).or_default().push(id);
}
if sym.file() == Some(file_id)
&& sym.ty() != STT_SECTION
&& let Some(r) = sym.input_section()
{
map.entry(r).or_default().push(id);
}
}
}
+74 -77
View File
@@ -261,17 +261,13 @@ fn mark_live_file<E: Arch>(ctx: &Context<E>, id: FileId) -> Vec<FileId> {
let id2 = file.symbols2[i];
let target =
if id2 != SymbolId::NONE { ctx.symbols[id2].file() } else { sym.file() };
if let Some(target) = target {
if (!target.is_dso() || !ctx.args.allow_shlib_undefined)
&& ctx.file(target).mark_reachable()
{
found.push(target);
if sym.is_traced() {
out!(
"trace-symbol: {file} keeps {} for {sym}",
ctx.file_display(target)
);
}
if let Some(target) = target
&& (!target.is_dso() || !ctx.args.allow_shlib_undefined)
&& ctx.file(target).mark_reachable()
{
found.push(target);
if sym.is_traced() {
out!("trace-symbol: {file} keeps {} for {sym}", ctx.file_display(target));
}
}
}
@@ -741,11 +737,11 @@ pub fn resolve_symbols<E: Arch>(ctx: &mut Context<E>) {
let mut roots = Vec::new();
for &id in &hidden {
if let Some(file) = ctx.symbols[id].file() {
if !ctx.file(file).is_reachable() {
ctx.file(file).set_reachable(true);
roots.push(file);
}
if let Some(file) = ctx.symbols[id].file()
&& !ctx.file(file).is_reachable()
{
ctx.file(file).set_reachable(true);
roots.push(file);
}
}
mark_live_files(ctx, roots);
@@ -1723,10 +1719,10 @@ pub fn check_duplicate_symbols<E: Arch>(ctx: &Context<E>) {
// Skip if one side is an LTO IR object and the other is not.
// The LTO backend resolves conflicts between IR and regular objects
// on its own; only IR-vs-IR duplicates need to be caught here.
if let FileId::Obj(o) = owner {
if ctx.objs[o.index()].is_lto_input() != file.is_lto_input() {
continue;
}
if let FileId::Obj(o) = owner
&& ctx.objs[o.index()].is_lto_input() != file.is_lto_input()
{
continue;
}
error!("duplicate symbol: {file}: {}: {sym}", ctx.file_display(owner));
}
@@ -1762,15 +1758,16 @@ pub fn check_symbol_version_conflicts<E: Arch>(ctx: &Context<E>) {
return;
}
let sym2 = &ctx.symbols[id2];
if let Some(FileId::Obj(_)) = sym2.file() {
if !sym2.is_weak() && sym2.ver_idx as u32 == (sym.ver_idx as u32 & !VERSYM_HIDDEN) {
let file = &ctx.objs[obj.index()];
error!(
"duplicate symbol: {file}: {}: {}",
ctx.file_display(sym2.file().unwrap()),
crate::util::display(file.base.symbol_name_in(sym.sym_idx() as usize))
);
}
if let Some(FileId::Obj(_)) = sym2.file()
&& !sym2.is_weak()
&& sym2.ver_idx as u32 == (sym.ver_idx as u32 & !VERSYM_HIDDEN)
{
let file = &ctx.objs[obj.index()];
error!(
"duplicate symbol: {file}: {}: {}",
ctx.file_display(sym2.file().unwrap()),
crate::util::display(file.base.symbol_name_in(sym.sym_idx() as usize))
);
}
});
crate::error::checkpoint();
@@ -1895,19 +1892,18 @@ pub fn check_symbol_types<E: Arch>(ctx: &Context<E>) {
};
let check = |file: &dyn std::fmt::Display, file_id: FileId, sym: &Symbol, st_type2: u32| {
let esym1 = &sym.esym(ctx);
if let Some(owner) = sym.file() {
if owner != file_id
&& esym1.st_type() != STT_NOTYPE
&& st_type2 != STT_NOTYPE
&& canonicalize(esym1.st_type()) != canonicalize(st_type2)
{
warn!(
"symbol type mismatch: {sym}\n>>> defined in {} as {}\n>>> defined in {file} as {}",
ctx.file_display(owner),
stt_to_string(esym1.st_type()),
stt_to_string(st_type2)
);
}
if let Some(owner) = sym.file()
&& owner != file_id
&& esym1.st_type() != STT_NOTYPE
&& st_type2 != STT_NOTYPE
&& canonicalize(esym1.st_type()) != canonicalize(st_type2)
{
warn!(
"symbol type mismatch: {sym}\n>>> defined in {} as {}\n>>> defined in {file} as {}",
ctx.file_display(owner),
stt_to_string(esym1.st_type()),
stt_to_string(st_type2)
);
}
};
@@ -2249,10 +2245,10 @@ pub fn compute_section_sizes<E: Arch>(ctx: &mut Context<E>) {
// create_range_extension_thunks is not thread-safe
for i in 0..ctx.chunks.len() {
let id = ctx.chunks[i];
if let ChunkId::Output(osec) = id {
if needs_thunks(ctx, id) {
crate::thunks::create_range_extension_thunks(ctx, osec);
}
if let ChunkId::Output(osec) = id
&& needs_thunks(ctx, id)
{
crate::thunks::create_range_extension_thunks(ctx, osec);
}
}
@@ -2349,10 +2345,10 @@ pub fn claim_unresolved_symbols<E: Arch>(ctx: &mut Context<E>) {
{
let sym = &ctx.symbols[id];
if let Some(owner) = sym.file() {
if !sym.is_undef() || ctx.file(owner).priority <= priority {
continue;
}
if let Some(owner) = sym.file()
&& (!sym.is_undef() || ctx.file(owner).priority <= priority)
{
continue;
}
}
@@ -2895,16 +2891,17 @@ pub fn parse_symbol_version<E: Arch>(ctx: &mut Context<E>) {
// versioned symbol. Likewise, if `foo@VERSION` and `foo@@VERSION` are
// defined, the default one takes precedence.
let sym_name = ctx.symbols[id].name();
if let Some(id2) = ctx.symbols.lookup(sym_name) {
if id2 != id && ctx.symbols[id2].file() == Some(file_id) {
let sym2_idx = ctx.symbols[id2].sym_idx() as usize;
if !file.has_symver[sym2_idx - file.base.first_global] {
let v2 = ctx.symbols[id2].ver_idx as u32;
if v2 == ctx.default_version as u32
|| (v2 & !VERSYM_HIDDEN) == (ver_idx as u32 & !VERSYM_HIDDEN)
{
ctx.symbols[id2].ver_idx = VER_NDX_LOCAL as u16;
}
if let Some(id2) = ctx.symbols.lookup(sym_name)
&& id2 != id
&& ctx.symbols[id2].file() == Some(file_id)
{
let sym2_idx = ctx.symbols[id2].sym_idx() as usize;
if !file.has_symver[sym2_idx - file.base.first_global] {
let v2 = ctx.symbols[id2].ver_idx as u32;
if v2 == ctx.default_version as u32
|| (v2 & !VERSYM_HIDDEN) == (ver_idx as u32 & !VERSYM_HIDDEN)
{
ctx.symbols[id2].ver_idx = VER_NDX_LOCAL as u16;
}
}
}
@@ -3155,10 +3152,10 @@ pub fn compute_address_significance<E: Arch>(ctx: &mut Context<E>) {
for r in isec.rels(file) {
if !r.is_func_call::<E>() {
let sym = &ctx_ref.symbols[file.base.symbols[r.r_sym() as usize]];
if let Some(dst) = sym.input_section_ref(ctx_ref) {
if dst.sh_flags & SHF_EXECINSTR as u64 != 0 {
dst.set_address_taken();
}
if let Some(dst) = sym.input_section_ref(ctx_ref)
&& dst.sh_flags & SHF_EXECINSTR as u64 != 0
{
dst.set_address_taken();
}
}
}
@@ -3820,14 +3817,14 @@ pub fn fix_synthetic_symbols<E: Arch>(ctx: &mut Context<E>) {
start(ctx, ctx.syms.bss_start, Some(bss), 0);
}
if let Some(ehdr) = &ctx.ehdr {
if ehdr.is_alloc() {
let addr = ehdr.shdr.sh_addr.get();
for sym in [ctx.syms.ehdr_start, ctx.syms.executable_start] {
if let (Some(sym), Some(first)) = (sym, first) {
let s = ctx.set_symbol_output_chunk(sym, first);
s.value = addr;
}
if let Some(ehdr) = &ctx.ehdr
&& ehdr.is_alloc()
{
let addr = ehdr.shdr.sh_addr.get();
for sym in [ctx.syms.ehdr_start, ctx.syms.executable_start] {
if let (Some(sym), Some(first)) = (sym, first) {
let s = ctx.set_symbol_output_chunk(sym, first);
s.value = addr;
}
}
}
@@ -3925,11 +3922,11 @@ pub fn fix_synthetic_symbols<E: Arch>(ctx: &mut Context<E>) {
}
}
// ARM32's __exidx_{start,end}
if ctx.syms.exidx_start.is_some() {
if let Some(c) = find(ctx, b".ARM.exidx") {
start(ctx, ctx.syms.exidx_start, Some(c), 0);
stop(ctx, ctx.syms.exidx_end, Some(c), 0);
}
if ctx.syms.exidx_start.is_some()
&& let Some(c) = find(ctx, b".ARM.exidx")
{
start(ctx, ctx.syms.exidx_start, Some(c), 0);
stop(ctx, ctx.syms.exidx_end, Some(c), 0);
}
// PPC64's ".TOC." symbol.
if E::IS_PPC64 {
+19 -23
View File
@@ -205,26 +205,22 @@ pub fn detect_machine_type<E: Arch>(ctx: &mut Context<E>, jobs: &[ReaderJob]) ->
if job.is_lib {
continue;
}
if let Some(mf) = open_file(&ctx.args.chroot, &job.name) {
if get_file_type(ctx, mf) != FileType::Text {
if let Some(target) =
filetype::get_machine_type(&ctx.args.plugin, &ctx.args.chroot, mf)
{
return target;
}
}
if let Some(mf) = open_file(&ctx.args.chroot, &job.name)
&& get_file_type(ctx, mf) != FileType::Text
&& let Some(target) = filetype::get_machine_type(&ctx.args.plugin, &ctx.args.chroot, mf)
{
return target;
}
}
for job in jobs {
if job.is_lib {
continue;
}
if let Some(mf) = open_file(&ctx.args.chroot, &job.name) {
if get_file_type(ctx, mf) == FileType::Text {
if let Some(target) = crate::linker_script::output_target(ctx, &job.rctx, mf) {
return target;
}
}
if let Some(mf) = open_file(&ctx.args.chroot, &job.name)
&& get_file_type(ctx, mf) == FileType::Text
&& let Some(target) = crate::linker_script::output_target(ctx, &job.rctx, mf)
{
return target;
}
}
fatal!("-m option is missing");
@@ -236,15 +232,15 @@ fn open_library<E: Arch>(
path: &std::path::Path,
) -> Option<&'static MappedFile> {
let mf = open_file(&ctx.args.chroot, path)?;
if let Some(target) = get_machine_type(ctx, rctx, mf) {
if target != E::NAME {
warn!(
"{}: skipping incompatible file: {target} (e_machine {})",
path.display(),
E::E_MACHINE
);
return None;
}
if let Some(target) = get_machine_type(ctx, rctx, mf)
&& target != E::NAME
{
warn!(
"{}: skipping incompatible file: {target} (e_machine {})",
path.display(),
E::E_MACHINE
);
return None;
}
Some(mf)
}
+4 -4
View File
@@ -127,10 +127,10 @@ fn claim_unresolved_symbols<E: Arch>(ctx: &mut Context<E>) {
}
let id = file.base.symbols[i];
let sym = &ctx.symbols[id];
if let Some(owner) = sym.file() {
if !sym.is_undef() || ctx.file(owner).priority <= priority {
continue;
}
if let Some(owner) = sym.file()
&& (!sym.is_undef() || ctx.file(owner).priority <= priority)
{
continue;
}
let sym = &mut ctx.symbols[id];
sym.set_file(FileId::Obj(file.id()));
+4 -4
View File
@@ -1219,10 +1219,10 @@ impl Symbol {
impl fmt::Display for Symbol {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if demangle_enabled() {
if let Some(name) = self.demangled() {
return f.write_str(&name);
}
if demangle_enabled()
&& let Some(name) = self.demangled()
{
return f.write_str(&name);
}
write!(f, "{}", self.name())
}
+4 -4
View File
@@ -127,10 +127,10 @@ impl Pattern {
}
fn matches(&self, s: &[u8]) -> bool {
if let Some(Token::Str(suffix)) = self.tokens.last() {
if !s.ends_with(suffix) {
return false;
}
if let Some(Token::Str(suffix)) = self.tokens.last()
&& !s.ends_with(suffix)
{
return false;
}
let mut x = 0;
+6 -6
View File
@@ -250,12 +250,12 @@ fn native_machine() -> String {
return canonical_machine(&machine.to_string_lossy());
}
if let Ok(output) = Command::new("cc").arg("-dumpmachine").output() {
if output.status.success() {
let triple = String::from_utf8_lossy(&output.stdout);
if !triple.trim().is_empty() {
return machine_from_triple(&triple);
}
if let Ok(output) = Command::new("cc").arg("-dumpmachine").output()
&& output.status.success()
{
let triple = String::from_utf8_lossy(&output.stdout);
if !triple.trim().is_empty() {
return machine_from_triple(&triple);
}
}
canonical_machine(env::consts::ARCH)