summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2022-11-08 13:21:25 -0500
committerpommicket <pommicket@gmail.com>2022-11-08 13:21:25 -0500
commitf4b03a64a183ee9f5102415a21ccfd098c87ab6d (patch)
tree395903ad88efb6044af03895ff22f12a6e154d2e
parentd2b519d5cd43236e8f23a5ca05b8e6e31346d241 (diff)
warning for multiple definitions of symbol
-rw-r--r--src/linker.rs8
-rw-r--r--src/main.rs5
-rw-r--r--test.c9
3 files changed, 16 insertions, 6 deletions
diff --git a/src/linker.rs b/src/linker.rs
index b1ee0a8..f4b4237 100644
--- a/src/linker.rs
+++ b/src/linker.rs
@@ -121,6 +121,8 @@ pub enum LinkWarning {
RelUnsupported(u8),
/// relocation is too large
RelOOB(String, u64),
+ /// multiple definitions of a symbol
+ MultipleDefinitions(String),
}
impl fmt::Display for LinkWarning {
@@ -129,6 +131,7 @@ impl fmt::Display for LinkWarning {
match self {
RelOOB(source, offset) => write!(f, "relocation {source}+0x{offset:x} goes outside of its section (it will be ignored)."),
RelUnsupported(x) => write!(f, "Unsupported relocation type {x} (relocation ignored)."),
+ MultipleDefinitions(name) => write!(f, "Symbol {name} has multiple definitions. One of them will be chosen arbitrarily."),
}
}
}
@@ -940,10 +943,13 @@ impl<'a> Linker<'a> {
symbol: &elf::Symbol,
) -> ObjectResult<()> {
let name = elf.symbol_name(symbol)?;
- // let dbg_name = name.clone();
let name_id = self.symbol_names.add(name);
let size = symbol.size;
+ if self.symbols.get_id_from_name(source, name_id).is_some() {
+ self.emit_warning(LinkWarning::MultipleDefinitions(elf.symbol_name(symbol)?));
+ }
+
let value = match symbol.value {
elf::SymbolValue::Undefined => None,
elf::SymbolValue::Absolute(n) => Some(SymbolValue::Absolute(n)),
diff --git a/src/main.rs b/src/main.rs
index 926b1e4..201b649 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,8 +1,5 @@
/*
@TODO:
-- what happens when a symbol has two definitions? can this happen with multiple c++ files which use the same template?
-- disable "warning: relocation XXX not in a data/text section" for .rel.eh_frame + maybe others
- - these warnings are being generated in two places. do they need to be?
- make executables more tiny (overlap sections, etc.)
- generate a warning/error on position-independent object files
- static libraries
@@ -28,7 +25,7 @@ struct Args {
no_std_lib: bool,
/// If set, the program will be linked against libstdc++.
///
- /// This is needed when using the standard template library.
+ /// This is needed when using any C++ library functions.
#[arg(long = "stdc++", default_value_t = false)]
std_cpp: bool,
/// Output executable path.
diff --git a/test.c b/test.c
index 1ec95d1..83253e0 100644
--- a/test.c
+++ b/test.c
@@ -1,6 +1,13 @@
+// temporary test file
+
#include<stdio.h>
#include <stdlib.h>
+int f() {
+ return 7;
+}
+
+
void entry(void) {
- printf("hi\n");
+ printf("%d\n", f());
exit(0);
}