Skip to content

Commit 485aec4

Browse files
author
Kai Luo
committed
Add AixLinker to support linking on AIX
1 parent 1c771fe commit 485aec4

File tree

1 file changed

+173
-0
lines changed

1 file changed

+173
-0
lines changed

compiler/rustc_codegen_ssa/src/back/linker.rs

Lines changed: 173 additions & 0 deletions
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,176 @@ 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 L4Re");
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+
Strip::Debuginfo => {}
1609+
Strip::Symbols => {
1610+
self.cmd.arg("-s");
1611+
}
1612+
}
1613+
}
1614+
1615+
fn no_crt_objects(&mut self) {}
1616+
1617+
fn no_default_libraries(&mut self) {}
1618+
1619+
fn export_symbols(&mut self, tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
1620+
let path = tmpdir.join("list.exp");
1621+
let res: io::Result<()> = try {
1622+
let mut f = BufWriter::new(File::create(&path)?);
1623+
// TODO: use llvm-nm to generate export list.
1624+
for symbol in symbols {
1625+
debug!(" _{}", symbol);
1626+
writeln!(f, " {}", symbol)?;
1627+
}
1628+
};
1629+
if let Err(e) = res {
1630+
self.sess.fatal(&format!("failed to write export file: {}", e));
1631+
}
1632+
self.cmd.arg(format!("-bE:{}", path.to_str().unwrap()));
1633+
}
1634+
1635+
fn subsystem(&mut self, _subsystem: &str) {}
1636+
1637+
fn reset_per_library_state(&mut self) {
1638+
self.hint_dynamic();
1639+
}
1640+
1641+
fn linker_plugin_lto(&mut self) {}
1642+
1643+
fn add_eh_frame_header(&mut self) {}
1644+
1645+
fn add_no_exec(&mut self) {}
1646+
1647+
fn add_as_needed(&mut self) {}
1648+
}
1649+
14771650
fn for_each_exported_symbols_include_dep<'tcx>(
14781651
tcx: TyCtxt<'tcx>,
14791652
crate_type: CrateType,

0 commit comments

Comments
 (0)