Skip to content

Commit 5b0179b

Browse files
committed
---
yaml --- r: 11997 b: refs/heads/master c: 8e911cb h: refs/heads/master i: 11995: ce3b593 v: v3
1 parent 6f8d31d commit 5b0179b

File tree

4 files changed

+48
-34
lines changed

4 files changed

+48
-34
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 1695148b5de9e801c4fbbbadce2f576e511c1cc2
2+
refs/heads/master: 8e911cbd6565517530a6034aad7b7e49ef50e6a3
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
55
refs/heads/try: 2898dcc5d97da9427ac367542382b6239d9c0bbf

trunk/src/rustc/back/link.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,14 +505,43 @@ fn get_symbol_hash(ccx: @crate_ctxt, t: ty::t) -> str {
505505
ret hash;
506506
}
507507

508+
509+
// Name sanitation. LLVM will happily accept identifiers with weird names, but
510+
// gas doesn't!
511+
fn sanitize(s: str) -> str {
512+
let result = "";
513+
str::chars_iter(s) {|c|
514+
alt c {
515+
'@' { result += "_sbox_"; }
516+
'~' { result += "_ubox_"; }
517+
'*' { result += "_ptr_"; }
518+
'&' { result += "_ref_"; }
519+
',' { result += "_"; }
520+
521+
'{' | '(' { result += "_of_"; }
522+
'a' to 'z'
523+
| 'A' to 'Z'
524+
| '0' to '9'
525+
| '_' { str::push_char(result,c); }
526+
_ {
527+
if c > 'z' && char::is_XID_continue(c) {
528+
str::push_char(result,c);
529+
}
530+
}
531+
}
532+
}
533+
ret result;
534+
}
535+
508536
fn mangle(ss: path) -> str {
509537
// Follow C++ namespace-mangling style
510538

511539
let n = "_ZN"; // Begin name-sequence.
512540

513541
for s in ss {
514542
alt s { path_name(s) | path_mod(s) {
515-
n += #fmt["%u%s", str::len(s), s];
543+
let sani = sanitize(s);
544+
n += #fmt["%u%s", str::len(sani), sani];
516545
} }
517546
}
518547
n += "E"; // End name-sequence.

trunk/src/rustc/middle/trans/base.rs

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -128,34 +128,6 @@ fn get_dest_addr(dest: dest) -> ValueRef {
128128
}
129129
}
130130

131-
// Name sanitation. LLVM will happily accept identifiers with weird names, but
132-
// gas doesn't!
133-
fn sanitize(s: str) -> str {
134-
let result = "";
135-
for c: u8 in s {
136-
if c == '@' as u8 {
137-
result += "boxed_";
138-
} else {
139-
if c == ',' as u8 {
140-
result += "_";
141-
} else {
142-
if c == '{' as u8 || c == '(' as u8 {
143-
result += "_of_";
144-
} else {
145-
if c != 10u8 && c != '}' as u8 && c != ')' as u8 &&
146-
c != ' ' as u8 && c != '\t' as u8 && c != ';' as u8
147-
{
148-
let v = [c];
149-
result += str::from_bytes(v);
150-
}
151-
}
152-
}
153-
}
154-
}
155-
ret result;
156-
}
157-
158-
159131
fn log_fn_time(ccx: @crate_ctxt, name: str, start: time::timeval,
160132
end: time::timeval) {
161133
let elapsed = 1000 * ((end.sec - start.sec) as int) +
@@ -412,6 +384,14 @@ fn set_glue_inlining(f: ValueRef, t: ty::t) {
412384
} else { set_always_inline(f); }
413385
}
414386

387+
// Double-check that we never ask LLVM to declare the same symbol twice. It
388+
// silently mangles such symbols, breaking our linkage model.
389+
fn note_unique_llvm_symbol(ccx: @crate_ctxt, sym: str) {
390+
if ccx.all_llvm_symbols.contains_key(sym) {
391+
ccx.sess.bug("duplicate LLVM symbol: " + sym);
392+
}
393+
ccx.all_llvm_symbols.insert(sym, ());
394+
}
415395

416396
// Generates the declaration for (but doesn't emit) a type descriptor.
417397
fn declare_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
@@ -424,8 +404,8 @@ fn declare_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
424404
let name;
425405
if ccx.sess.opts.debuginfo {
426406
name = mangle_internal_name_by_type_only(ccx, t, "tydesc");
427-
name = sanitize(name);
428407
} else { name = mangle_internal_name_by_seq(ccx, "tydesc"); }
408+
note_unique_llvm_symbol(ccx, name);
429409
let gvar = str::as_c_str(name, {|buf|
430410
llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type, buf)
431411
});
@@ -449,8 +429,10 @@ fn declare_generic_glue(ccx: @crate_ctxt, t: ty::t, llfnty: TypeRef,
449429
let fn_nm;
450430
if ccx.sess.opts.debuginfo {
451431
fn_nm = mangle_internal_name_by_type_only(ccx, t, "glue_" + name);
452-
fn_nm = sanitize(fn_nm);
453-
} else { fn_nm = mangle_internal_name_by_seq(ccx, "glue_" + name); }
432+
} else {
433+
fn_nm = mangle_internal_name_by_seq(ccx, "glue_" + name);
434+
}
435+
note_unique_llvm_symbol(ccx, fn_nm);
454436
let llfn = decl_cdecl_fn(ccx.llmod, fn_nm, llfnty);
455437
set_glue_inlining(llfn, t);
456438
ret llfn;
@@ -4414,6 +4396,7 @@ fn trans_constant(ccx: @crate_ctxt, it: @ast::item) {
44144396
path_name("discrim")];
44154397
let s = mangle_exported_name(ccx, p, ty::mk_int(ccx.tcx));
44164398
let disr_val = vi[i].disr_val;
4399+
note_unique_llvm_symbol(ccx, s);
44174400
let discrim_gvar = str::as_c_str(s, {|buf|
44184401
llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf)
44194402
});
@@ -4669,6 +4652,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
46694652
sha: sha,
46704653
type_sha1s: ty::new_ty_hash(),
46714654
type_short_names: ty::new_ty_hash(),
4655+
all_llvm_symbols: str_hash::<()>(),
46724656
tcx: tcx,
46734657
maps: maps,
46744658
stats:

trunk/src/rustc/middle/trans/common.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import libc::c_uint;
77
import vec::unsafe::to_ptr;
8-
import std::map::hashmap;
8+
import std::map::{hashmap,set};
99
import syntax::ast;
1010
import driver::session;
1111
import session::session;
@@ -101,6 +101,7 @@ type crate_ctxt = {
101101
sha: std::sha1::sha1,
102102
type_sha1s: hashmap<ty::t, str>,
103103
type_short_names: hashmap<ty::t, str>,
104+
all_llvm_symbols: set<str>,
104105
tcx: ty::ctxt,
105106
maps: maps,
106107
stats: stats,

0 commit comments

Comments
 (0)