Skip to content

Commit 686bd46

Browse files
authored
Rollup merge of #109515 - bzEq:aix-linker, r=petrochenkov
Add AixLinker to support linking on AIX AIX linker has a different cli style from other existing linkers. It is documented in https://www.ibm.com/docs/en/aix/7.1?topic=l-ld-command.
2 parents 1c7ef3b + 3957d3a commit 686bd46

File tree

1 file changed

+174
-0
lines changed

1 file changed

+174
-0
lines changed

compiler/rustc_codegen_ssa/src/back/linker.rs

+174
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ pub fn get_linker<'a>(
133133
LinkerFlavor::Unix(Cc::No) if sess.target.os == "l4re" => {
134134
Box::new(L4Bender::new(cmd, sess)) as Box<dyn Linker>
135135
}
136+
LinkerFlavor::Unix(Cc::No) if sess.target.os == "aix" => {
137+
Box::new(AixLinker::new(cmd, sess)) as Box<dyn Linker>
138+
}
136139
LinkerFlavor::WasmLld(Cc::No) => Box::new(WasmLd::new(cmd, sess)) as Box<dyn Linker>,
137140
LinkerFlavor::Gnu(cc, _)
138141
| LinkerFlavor::Darwin(cc, _)
@@ -1474,6 +1477,177 @@ impl<'a> L4Bender<'a> {
14741477
}
14751478
}
14761479

1480+
/// Linker for AIX.
1481+
pub struct AixLinker<'a> {
1482+
cmd: Command,
1483+
sess: &'a Session,
1484+
hinted_static: bool,
1485+
}
1486+
1487+
impl<'a> AixLinker<'a> {
1488+
pub fn new(cmd: Command, sess: &'a Session) -> AixLinker<'a> {
1489+
AixLinker { cmd: cmd, sess: sess, hinted_static: false }
1490+
}
1491+
1492+
fn hint_static(&mut self) {
1493+
if !self.hinted_static {
1494+
self.cmd.arg("-bstatic");
1495+
self.hinted_static = true;
1496+
}
1497+
}
1498+
1499+
fn hint_dynamic(&mut self) {
1500+
if self.hinted_static {
1501+
self.cmd.arg("-bdynamic");
1502+
self.hinted_static = false;
1503+
}
1504+
}
1505+
1506+
fn build_dylib(&mut self, _out_filename: &Path) {
1507+
self.cmd.arg("-bM:SRE");
1508+
self.cmd.arg("-bnoentry");
1509+
// FIXME: Use CreateExportList utility to create export list
1510+
// and remove -bexpfull.
1511+
self.cmd.arg("-bexpfull");
1512+
}
1513+
}
1514+
1515+
impl<'a> Linker for AixLinker<'a> {
1516+
fn link_dylib(&mut self, lib: &str, _verbatim: bool, _as_needed: bool) {
1517+
self.hint_dynamic();
1518+
self.cmd.arg(format!("-l{}", lib));
1519+
}
1520+
1521+
fn link_staticlib(&mut self, lib: &str, _verbatim: bool) {
1522+
self.hint_static();
1523+
self.cmd.arg(format!("-l{}", lib));
1524+
}
1525+
1526+
fn link_rlib(&mut self, lib: &Path) {
1527+
self.hint_static();
1528+
self.cmd.arg(lib);
1529+
}
1530+
1531+
fn include_path(&mut self, path: &Path) {
1532+
self.cmd.arg("-L").arg(path);
1533+
}
1534+
1535+
fn framework_path(&mut self, _: &Path) {
1536+
bug!("frameworks are not supported on AIX");
1537+
}
1538+
1539+
fn output_filename(&mut self, path: &Path) {
1540+
self.cmd.arg("-o").arg(path);
1541+
}
1542+
1543+
fn add_object(&mut self, path: &Path) {
1544+
self.cmd.arg(path);
1545+
}
1546+
1547+
fn full_relro(&mut self) {}
1548+
1549+
fn partial_relro(&mut self) {}
1550+
1551+
fn no_relro(&mut self) {}
1552+
1553+
fn cmd(&mut self) -> &mut Command {
1554+
&mut self.cmd
1555+
}
1556+
1557+
fn set_output_kind(&mut self, output_kind: LinkOutputKind, out_filename: &Path) {
1558+
match output_kind {
1559+
LinkOutputKind::DynamicDylib => {
1560+
self.hint_dynamic();
1561+
self.build_dylib(out_filename);
1562+
}
1563+
LinkOutputKind::StaticDylib => {
1564+
self.hint_static();
1565+
self.build_dylib(out_filename);
1566+
}
1567+
_ => {}
1568+
}
1569+
}
1570+
1571+
fn link_rust_dylib(&mut self, lib: &str, _: &Path) {
1572+
self.hint_dynamic();
1573+
self.cmd.arg(format!("-l{}", lib));
1574+
}
1575+
1576+
fn link_framework(&mut self, _framework: &str, _as_needed: bool) {
1577+
bug!("frameworks not supported on AIX");
1578+
}
1579+
1580+
fn link_whole_staticlib(&mut self, lib: &str, verbatim: bool, search_path: &[PathBuf]) {
1581+
self.hint_static();
1582+
let lib = find_native_static_library(lib, verbatim, search_path, &self.sess);
1583+
self.cmd.arg(format!("-bkeepfile:{}", lib.to_str().unwrap()));
1584+
}
1585+
1586+
fn link_whole_rlib(&mut self, lib: &Path) {
1587+
self.hint_static();
1588+
self.cmd.arg(format!("-bkeepfile:{}", lib.to_str().unwrap()));
1589+
}
1590+
1591+
fn gc_sections(&mut self, _keep_metadata: bool) {
1592+
self.cmd.arg("-bgc");
1593+
}
1594+
1595+
fn no_gc_sections(&mut self) {
1596+
self.cmd.arg("-bnogc");
1597+
}
1598+
1599+
fn optimize(&mut self) {}
1600+
1601+
fn pgo_gen(&mut self) {}
1602+
1603+
fn control_flow_guard(&mut self) {}
1604+
1605+
fn debuginfo(&mut self, strip: Strip, _: &[PathBuf]) {
1606+
match strip {
1607+
Strip::None => {}
1608+
// FIXME: -s strips the symbol table, line number information
1609+
// and relocation information.
1610+
Strip::Debuginfo | Strip::Symbols => {
1611+
self.cmd.arg("-s");
1612+
}
1613+
}
1614+
}
1615+
1616+
fn no_crt_objects(&mut self) {}
1617+
1618+
fn no_default_libraries(&mut self) {}
1619+
1620+
fn export_symbols(&mut self, tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
1621+
let path = tmpdir.join("list.exp");
1622+
let res: io::Result<()> = try {
1623+
let mut f = BufWriter::new(File::create(&path)?);
1624+
// TODO: use llvm-nm to generate export list.
1625+
for symbol in symbols {
1626+
debug!(" _{}", symbol);
1627+
writeln!(f, " {}", symbol)?;
1628+
}
1629+
};
1630+
if let Err(e) = res {
1631+
self.sess.fatal(&format!("failed to write export file: {}", e));
1632+
}
1633+
self.cmd.arg(format!("-bE:{}", path.to_str().unwrap()));
1634+
}
1635+
1636+
fn subsystem(&mut self, _subsystem: &str) {}
1637+
1638+
fn reset_per_library_state(&mut self) {
1639+
self.hint_dynamic();
1640+
}
1641+
1642+
fn linker_plugin_lto(&mut self) {}
1643+
1644+
fn add_eh_frame_header(&mut self) {}
1645+
1646+
fn add_no_exec(&mut self) {}
1647+
1648+
fn add_as_needed(&mut self) {}
1649+
}
1650+
14771651
fn for_each_exported_symbols_include_dep<'tcx>(
14781652
tcx: TyCtxt<'tcx>,
14791653
crate_type: CrateType,

0 commit comments

Comments
 (0)